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, 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 F1BE9C43331 for ; Fri, 3 Apr 2020 09:41:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 961DB208E4 for ; Fri, 3 Apr 2020 09:41:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="R3m4KPK9" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2403881AbgDCJlW (ORCPT ); Fri, 3 Apr 2020 05:41:22 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:17455 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S2403809AbgDCJlR (ORCPT ); Fri, 3 Apr 2020 05:41:17 -0400 X-UUID: 87fa0d16e8744af595ff005dc0fd3cdb-20200403 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=C5GZe5ZHxZEA0bVUU+2nNLCD3vP43u8gHp5y89FHgvQ=; b=R3m4KPK9Zkat37vtzCYYLMaXoZ4hE/mlsY5FfU83x7fhHh7qR6eLSvmHNfB8bMrvDoNAO1PZ+UkBrbEv+S1osVGsx5G2pUoM6RxmMyv2V0T0RjccEuhofGbNEIjXlMlOqjqYSGlYsHL/uOq+0x/XERhAuRHnuG+vNFes7FdP9wU=; X-UUID: 87fa0d16e8744af595ff005dc0fd3cdb-20200403 Received: from mtkexhb01.mediatek.inc [(172.21.101.102)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1294976541; Fri, 03 Apr 2020 17:40:52 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 3 Apr 2020 17:40:48 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 3 Apr 2020 17:40:47 +0800 From: Xia Jiang To: Hans Verkuil , Mauro Carvalho Chehab , Rob Herring , Matthias Brugger , Rick Chang CC: , , , , , Marek Szyprowski , Tomasz Figa , , , , , , , Xia Jiang Subject: [PATCH v8 14/14] media: platform: Add jpeg dec/enc feature Date: Fri, 3 Apr 2020 17:40:33 +0800 Message-ID: <20200403094033.8288-15-xia.jiang@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20200403094033.8288-1-xia.jiang@mediatek.com> References: <20200403094033.8288-1-xia.jiang@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain 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 QWRkIG10ayBqcGVnIGVuY29kZSB2NGwyIGRyaXZlciBiYXNlZCBvbiBqcGVnIGRlY29kZSwgYmVj YXVzZSB0aGF0IGpwZWcNCmRlY29kZSBhbmQgZW5jb2RlIGhhdmUgZ3JlYXQgc2ltaWxhcml0aWVz IHdpdGggZnVuY3Rpb24gb3BlcmF0aW9uLg0KDQpTaWduZWQtb2ZmLWJ5OiBYaWEgSmlhbmcgPHhp YS5qaWFuZ0BtZWRpYXRlay5jb20+DQotLS0NCnY4OmpwZWcgZW5jb2RlciBhbmQgZGVjb2RlciB1 c2Ugc2VwYXJhdGUgY2FsbGJhY2tzIGluc3RlYWQgb2YgcmVwZWF0aW5nDQogICB0aGUgaWYvZWxz ZSBpbiBldmVyeSBjYWxsYmFjay4NCiAgIGltcHJvdmUgdmlkaW9jX3RyeV9mbXQoKSBpbXBsZW1l bnRhdGlvbiB0aGF0IGNhbiBiZSBzaGFyZWQgYnkganBlZw0KICAgZW5jb2RlciBhbmQgZGVjb2Rl ci4NCiAgIGZpeCB0aGUgYnVnIG9mIGpwZWcgZW5jb2RlciBzX3NlbGVjdGlvbiBpbXBsZW1lbnRh dGlvbi4NCiAgIGNhbmNlbCB0aGUgc3RhdGUgb2YgdGhlIGpwZWcgZW5jb2Rlci4NCiAgIGltcHJv dmUganBlZyBlbmNvZGVyIGFuZCBkZWNvZGVyIHNldCBkZWZhdWx0IHBhcmFtcyBmbG93Lg0KICAg cHV0IHRoZSBjbG9jayBuYW1lcyBhbmQgb3RoZXIgZGF0YXMgaW4gYSBtYXRjaF9kYXRhIHN0cnVj dC4NCiAgIGZpeCB0aGUgYnVnIG9mIGdldGluZyBjb3JyZWN0bHkgcXVhbGl0eSB2YWx1ZS4NCiAg IGRvIHRoZSBhbGwgdGhlIGJpdHMnIHNldHRpbmdzIG9mIG9uZSByZWdpc3RlciBpbiBvbmUgZnVu Y3Rpb24uDQogICBtb3ZlIHRoZSBjb2RlIG9mIG10a19qcGVnX2VuY19yZWcuaCB0byBtdGtfanBl Z19lbmNfaHcuaCBhbmQgZGVsZXRlDQogICBtdGtfanBlZ19lbmNfcmVnLmguDQoNCnY3OiByZXZl cnNlIHNwaW4gbG9jayBhbmQgdW5sb2NrIG9wZXJhdGlvbiBpbiBkZXZpY2UgcnVuIGZ1bmN0aW9u IGZvcg0KICAgIG11bHRpLWluc3RhbmNlLg0KDQp2NjogYWRkIHNwYWNlIHRvIGFyb3VuZGluZyAn KycuDQogICAgYWxpZ25tZW50ICdzdHJ1Y3QgbXRrX2pwZWdfZm10ICpmbXQnIG1hdGNoIG9wZW4g cGFyZW50aGVzaXMuDQogICAgY2hhbmdlICdtdGtfanBlZ19lbmNfc2V0X2VuY0Zvcm1hdCcgdG8g J210a19qcGVnX2VuY19zZXRfZW5jX2Zvcm1hdCcuDQogICAgbWFrZSAnbXRrX2pwZWdfY3RybHNf c2V0dXAnIHRvIHN0YXRpYyBwcm90b3R5cGUuDQogICAgZGVsZXRlIHVudXNlZCB2YXJpYWJsZXMg J2pwZWcnLydhbGlnbl9oJy8nYWxpZ25fdycvJ2ZsYWdzJy4NCiAgICBpbml0aWFsaXplICd5dXZf Zm9ybWF0Jy8nZW5jX3F1YWxpdHknIHZhcmlhYmxlcy4NCiAgICANCnY1OiBzdXBwb3J0IGNyb3Ag Zm9yIGVuY29kZXIgYW5kIGNvbXBvc2UgZm9yIGRlY29kZXIgaW4gc19zZWxlY3Rpb24gYW5kDQog ICAgZ19zZWxlY3Rpb24gZnVuY3Rpb24uDQogICAgdXNlIGNsYW1wKCkgdG8gcmVwbGFjZSBtdGtf anBlZ19ib3VuZF9hbGlnbl9pbWFnZSgpIGFuZCByb3VuZF91cCgpDQogICAgdG8gcmVwbGFjZSBt dGtfanBlZ19hbGlnbigpLg0KICAgIGRlbGV0ZSBqcGVnX2VuY19wYXJhbS9tdGtfanBlZ19lbmNf cGFyYW0gc3RydWN0dXJlIGFuZA0KICAgIG10a19qcGVnX3NldF9wYXJhbSgpLCBwcm9ncmFtIHRo ZSByZWdpc3RlcnMgZGlyZWN0bHkgYmFzZWQgb24NCiAgICB0aGUgb3JpZ2luYWwgVjRMMiB2YWx1 ZXMuDQogICAgbW92ZSBtYWNybyBkZWZpbml0aW9uIGFib3V0IGh3IHRvIG10a19qcGVnX2VuY19y ZWcuaC4NCiAgICBkZWxldGUgdW5uZWNlc3NhcnkgVjRMMiBsb2dzIGluIGRyaXZlci4NCiAgICBj YW5jZWwgc3BpbiBsb2NrIGFuZCB1bmxvY2sgb3BlcmF0aW9uIGluIGRldmllYyBydW4gZnVuY3Rp b24uDQogICAgY2hhbmdlIGpwZWcgZW5jIHJlZ2lzdGVyIG9mZnNldCBoZXggbnVtYmVyYWxzIGZy b20gdXBlcmNhc2UgdG8gbG93ZXJjYXNlLg0KDQp2NDogc3BsaXQgbXRrX2pwZWdfdHJ5X2ZtdF9t cGxhbmUoKSB0byB0d28gZnVuY3Rpb25zLCBvbmUgZm9yIGVuY29kZXIsICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgb25lIGZvciBkZWNv ZGVyLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICANCiAgICBzcGxpdCBtdGtfanBlZ19zZXRfZGVmYXVsdF9wYXJhbXMoKSB0byB0d28gZnVu Y3Rpb25zLCBvbmUgZm9yICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIA0KICAgIGVuY29kZXIsIG9uZSBmb3IgZGVjb2Rlci4gICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgYWRk IGNyb3BwaW5nIHN1cHBvcnQgZm9yIGVuY29kZXIgaW4gZy9zX3NlbGVjdGlvbiBpb2N0bHMuICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0K ICAgIGNoYW5nZSBleGlmIG1vZGUgc3VwcG9ydCBieSB1c2luZyBWNEwyX0pQRUdfQUNUSVZFX01B UktFUl9BUFAxLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIA0KICAgIGNoYW5nZSBNVEtfSlBFR19NQVhfV0lEVEgvTVRLX0pQRUdfTUFYX0hF SUdIIGZyb20gODE5MiB0byA2NTUzNSBieSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIA0KICAgIHNwZWNpZmljYXRpb24uICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgIG1vdmUgd2lk dGggc2hpZnRpbmcgb3BlcmF0aW9uIGJlaGluZCBhbGlnbmluZyBvcGVyYXRpb24gaW4gICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAg bXRrX2pwZWdfdHJ5X2VuY19mbXRfbXBsYW5lKCkgZm9yIGJ1ZyBmaXguICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgIGZpeCB1c2Vy IGFidXNlaW5nIGRhdGFfb2Zmc2V0IGlzc3VlIGZvciBETUFCVUYgaW4gICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgbXRrX2pwZWdf c2V0X2VuY19zcmMoKS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgDQogICAgZml4IGtidWlsZCB3YXJpbmdzOiBjaGFuZ2UgTVRLX0pQRUdf TUlOX0hFSUdIVC9NVEtfSlBFR19NQVhfSEVJR0hUICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICBhbmQg TVRLX0pQRUdfTUlOX1dJRFRIL01US19KUEVHX01BWF9XSURUSCBmcm9tICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAg ICAgICAgICAnaW50JyB0eXBlIHRvICd1bnNpZ25lZCBpbnQnIHR5cGUuICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAg ICAgICAgICAgICAgZml4IG1zbGVhZGluZ2x5IGluZGVudGVkIG9mICdlbHNlJy4gICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KdjM6IGRlbGV0ZSBD aGFuZ2UtSWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIA0KICAgIG9ubHkgdGVzdCBvbmNlIGhhbmRsZXItPmVycm9yIGFmdGVyIHRoZSBs YXN0IHY0bDJfY3RybF9uZXdfc3RkKCkuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIA0KICAgIHNlcGVyYXRlIGNoYW5nZXMgb2YgdjRsMi1jdHJs cy5jIGFuZCB2NGwyLWNvbnRyb2xzLmggdG8gbmV3IHBhdGNoLiAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KdjI6IGZpeCBjb21wbGlhbmNlIHRl c3QgZmFpbCwgY2hlY2sgY3JlYXRlZCBidWZmZXIgc2l6ZSBpbiBkcml2ZXIuDQotLS0NCiBkcml2 ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL01ha2VmaWxlICAgICAgfCAgICA1ICstDQogLi4u L21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVnX2NvcmUuYyAgIHwgMTAzOCArKysrKysr KysrKysrLS0tLQ0KIC4uLi9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19jb3JlLmgg ICB8ICAgNTEgKy0NCiAuLi4vbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfZGVjX2h3 LmggfCAgICA3ICstDQogLi4uL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVnX2VuY19o dy5jIHwgIDE5MyArKysNCiAuLi4vbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfZW5j X2h3LmggfCAgMTIzICsrDQogNiBmaWxlcyBjaGFuZ2VkLCAxMTg4IGluc2VydGlvbnMoKyksIDIy OSBkZWxldGlvbnMoLSkNCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9tZWRpYS9wbGF0Zm9y bS9tdGstanBlZy9tdGtfanBlZ19lbmNfaHcuYw0KIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJz L21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVnX2VuY19ody5oDQoNCmRpZmYgLS1naXQg YS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL01ha2VmaWxlIGIvZHJpdmVycy9tZWRp YS9wbGF0Zm9ybS9tdGstanBlZy9NYWtlZmlsZQ0KaW5kZXggNDg1MTZkY2Y5NmU2Li43NmMzM2Fh ZDBmM2YgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL01ha2Vm aWxlDQorKysgYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL01ha2VmaWxlDQpAQCAt MSwzICsxLDYgQEANCiAjIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkNCi1t dGtfanBlZy1vYmpzIDo9IG10a19qcGVnX2NvcmUubyBtdGtfanBlZ19kZWNfaHcubyBtdGtfanBl Z19kZWNfcGFyc2Uubw0KK210a19qcGVnLW9ianMgOj0gbXRrX2pwZWdfY29yZS5vIFwNCisJCSBt dGtfanBlZ19kZWNfaHcubyBcDQorCQkgbXRrX2pwZWdfZGVjX3BhcnNlLm8gXA0KKwkJIG10a19q cGVnX2VuY19ody5vDQogb2JqLSQoQ09ORklHX1ZJREVPX01FRElBVEVLX0pQRUcpICs9IG10a19q cGVnLm8NCmRpZmYgLS1naXQgYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19q cGVnX2NvcmUuYyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfY29y ZS5jDQppbmRleCA3N2E5NTE4NTU4NGMuLjE4YTc1OWNlMmM0NiAxMDA2NDQNCi0tLSBhL2RyaXZl cnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfY29yZS5jDQorKysgYi9kcml2ZXJz L21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVnX2NvcmUuYw0KQEAgLTMsNiArMyw3IEBA DQogICogQ29weXJpZ2h0IChjKSAyMDE2IE1lZGlhVGVrIEluYy4NCiAgKiBBdXRob3I6IE1pbmcg SHNpdSBUc2FpIDxtaW5naHNpdS50c2FpQG1lZGlhdGVrLmNvbT4NCiAgKiAgICAgICAgIFJpY2sg Q2hhbmcgPHJpY2suY2hhbmdAbWVkaWF0ZWsuY29tPg0KKyAqICAgICAgICAgWGlhIEppYW5nIDx4 aWEuamlhbmdAbWVkaWF0ZWsuY29tPg0KICAqLw0KIA0KICNpbmNsdWRlIDxsaW51eC9jbGsuaD4N CkBAIC0yMywxMSArMjQsNjAgQEANCiAjaW5jbHVkZSA8bWVkaWEvdmlkZW9idWYyLWRtYS1jb250 aWcuaD4NCiAjaW5jbHVkZSA8c29jL21lZGlhdGVrL3NtaS5oPg0KIA0KKyNpbmNsdWRlICJtdGtf anBlZ19lbmNfaHcuaCINCiAjaW5jbHVkZSAibXRrX2pwZWdfZGVjX2h3LmgiDQogI2luY2x1ZGUg Im10a19qcGVnX2NvcmUuaCINCiAjaW5jbHVkZSAibXRrX2pwZWdfZGVjX3BhcnNlLmgiDQogDQot c3RhdGljIHN0cnVjdCBtdGtfanBlZ19mbXQgbXRrX2pwZWdfZm9ybWF0c1tdID0gew0KK3N0YXRp YyBzdHJ1Y3QgbXRrX2pwZWdfZm10IG10a19qcGVnX2VuY19mb3JtYXRzW10gPSB7DQorCXsNCisJ CS5mb3VyY2MJCT0gVjRMMl9QSVhfRk1UX0pQRUcsDQorCQkuY29scGxhbmVzCT0gMSwNCisJCS5m bGFncwkJPSBNVEtfSlBFR19GTVRfRkxBR19FTkNfQ0FQVFVSRSwNCisJfSwNCisJew0KKwkJLmZv dXJjYwkJPSBWNEwyX1BJWF9GTVRfTlYxMk0sDQorCQkuaHdfZm9ybWF0CT0gSlBFR19FTkNfWVVW X0ZPUk1BVF9OVjEyLA0KKwkJLmhfc2FtcGxlCT0gezQsIDR9LA0KKwkJLnZfc2FtcGxlCT0gezQs IDJ9LA0KKwkJLmNvbHBsYW5lcwk9IDIsDQorCQkuaF9hbGlnbgk9IDQsDQorCQkudl9hbGlnbgk9 IDQsDQorCQkuZmxhZ3MJCT0gTVRLX0pQRUdfRk1UX0ZMQUdfRU5DX09VVFBVVCwNCisJfSwNCisJ ew0KKwkJLmZvdXJjYwkJPSBWNEwyX1BJWF9GTVRfTlYyMU0sDQorCQkuaHdfZm9ybWF0CT0gSkVQ R19FTkNfWVVWX0ZPUk1BVF9OVjIxLA0KKwkJLmhfc2FtcGxlCT0gezQsIDR9LA0KKwkJLnZfc2Ft cGxlCT0gezQsIDJ9LA0KKwkJLmNvbHBsYW5lcwk9IDIsDQorCQkuaF9hbGlnbgk9IDQsDQorCQku dl9hbGlnbgk9IDQsDQorCQkuZmxhZ3MJCT0gTVRLX0pQRUdfRk1UX0ZMQUdfRU5DX09VVFBVVCwN CisJfSwNCisJew0KKwkJLmZvdXJjYwkJPSBWNEwyX1BJWF9GTVRfWVVZViwNCisJCS5od19mb3Jt YXQJPSBKUEVHX0VOQ19ZVVZfRk9STUFUX1lVWVYsDQorCQkuaF9zYW1wbGUJPSB7OH0sDQorCQku dl9zYW1wbGUJPSB7NH0sDQorCQkuY29scGxhbmVzCT0gMSwNCisJCS5oX2FsaWduCT0gNSwNCisJ CS52X2FsaWduCT0gMywNCisJCS5mbGFncwkJPSBNVEtfSlBFR19GTVRfRkxBR19FTkNfT1VUUFVU LA0KKwl9LA0KKwl7DQorCQkuZm91cmNjCQk9IFY0TDJfUElYX0ZNVF9ZVllVLA0KKwkJLmh3X2Zv cm1hdAk9IEpQRUdfRU5DX1lVVl9GT1JNQVRfWVZZVSwNCisJCS5oX3NhbXBsZQk9IHs4fSwNCisJ CS52X3NhbXBsZQk9IHs0fSwNCisJCS5jb2xwbGFuZXMJPSAxLA0KKwkJLmhfYWxpZ24JPSA1LA0K KwkJLnZfYWxpZ24JPSAzLA0KKwkJLmZsYWdzCQk9IE1US19KUEVHX0ZNVF9GTEFHX0VOQ19PVVRQ VVQsDQorCX0sDQorfTsNCisNCitzdGF0aWMgc3RydWN0IG10a19qcGVnX2ZtdCBtdGtfanBlZ19k ZWNfZm9ybWF0c1tdID0gew0KIAl7DQogCQkuZm91cmNjCQk9IFY0TDJfUElYX0ZNVF9KUEVHLA0K IAkJLmNvbHBsYW5lcwk9IDEsDQpAQCAtNTMsNyArMTAzLDggQEAgc3RhdGljIHN0cnVjdCBtdGtf anBlZ19mbXQgbXRrX2pwZWdfZm9ybWF0c1tdID0gew0KIAl9LA0KIH07DQogDQotI2RlZmluZSBN VEtfSlBFR19OVU1fRk9STUFUUyBBUlJBWV9TSVpFKG10a19qcGVnX2Zvcm1hdHMpDQorI2RlZmlu ZSBNVEtfSlBFR19FTkNfTlVNX0ZPUk1BVFMgQVJSQVlfU0laRShtdGtfanBlZ19lbmNfZm9ybWF0 cykNCisjZGVmaW5lIE1US19KUEVHX0RFQ19OVU1fRk9STUFUUyBBUlJBWV9TSVpFKG10a19qcGVn X2RlY19mb3JtYXRzKQ0KIA0KIGVudW0gew0KIAlNVEtfSlBFR19CVUZfRkxBR1NfSU5JVAkJCT0g MCwNCkBAIC03MCw2ICsxMjEsMTEgQEAgc3RydWN0IG10a19qcGVnX3NyY19idWYgew0KIHN0YXRp YyBpbnQgZGVidWc7DQogbW9kdWxlX3BhcmFtKGRlYnVnLCBpbnQsIDA2NDQpOw0KIA0KK3N0YXRp YyBpbmxpbmUgc3RydWN0IG10a19qcGVnX2N0eCAqY3RybF90b19jdHgoc3RydWN0IHY0bDJfY3Ry bCAqY3RybCkNCit7DQorCXJldHVybiBjb250YWluZXJfb2YoY3RybC0+aGFuZGxlciwgc3RydWN0 IG10a19qcGVnX2N0eCwgY3RybF9oZGwpOw0KK30NCisNCiBzdGF0aWMgaW5saW5lIHN0cnVjdCBt dGtfanBlZ19jdHggKm10a19qcGVnX2ZoX3RvX2N0eChzdHJ1Y3QgdjRsMl9maCAqZmgpDQogew0K IAlyZXR1cm4gY29udGFpbmVyX29mKGZoLCBzdHJ1Y3QgbXRrX2pwZWdfY3R4LCBmaCk7DQpAQCAt ODEsMTIgKzEzNywyNSBAQCBzdGF0aWMgaW5saW5lIHN0cnVjdCBtdGtfanBlZ19zcmNfYnVmICpt dGtfanBlZ192YjJfdG9fc3JjYnVmKA0KIAlyZXR1cm4gY29udGFpbmVyX29mKHRvX3ZiMl92NGwy X2J1ZmZlcih2YiksIHN0cnVjdCBtdGtfanBlZ19zcmNfYnVmLCBiKTsNCiB9DQogDQotc3RhdGlj IGludCBtdGtfanBlZ19xdWVyeWNhcChzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCi0J CQkgICAgIHN0cnVjdCB2NGwyX2NhcGFiaWxpdHkgKmNhcCkNCitzdGF0aWMgaW50IG10a19qcGVn X2VuY19xdWVyeWNhcChzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCisJCQkJIHN0cnVj dCB2NGwyX2NhcGFiaWxpdHkgKmNhcCkNCit7DQorCXN0cnVjdCBtdGtfanBlZ19kZXYgKmpwZWcg PSB2aWRlb19kcnZkYXRhKGZpbGUpOw0KKw0KKwlzdHJzY3B5KGNhcC0+ZHJpdmVyLCBNVEtfSlBF R19OQU1FLCBzaXplb2YoY2FwLT5kcml2ZXIpKTsNCisJc3Ryc2NweShjYXAtPmNhcmQsIE1US19K UEVHX05BTUUgIiBlbmNvZGVyIiwgc2l6ZW9mKGNhcC0+Y2FyZCkpOw0KKwlzbnByaW50ZihjYXAt PmJ1c19pbmZvLCBzaXplb2YoY2FwLT5idXNfaW5mbyksICJwbGF0Zm9ybTolcyIsDQorCQkgZGV2 X25hbWUoanBlZy0+ZGV2KSk7DQorDQorCXJldHVybiAwOw0KK30NCisNCitzdGF0aWMgaW50IG10 a19qcGVnX2RlY19xdWVyeWNhcChzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCisJCQkJ IHN0cnVjdCB2NGwyX2NhcGFiaWxpdHkgKmNhcCkNCiB7DQogCXN0cnVjdCBtdGtfanBlZ19kZXYg KmpwZWcgPSB2aWRlb19kcnZkYXRhKGZpbGUpOw0KIA0KLQlzdHJzY3B5KGNhcC0+ZHJpdmVyLCBN VEtfSlBFR19OQU1FICIgZGVjb2RlciIsIHNpemVvZihjYXAtPmRyaXZlcikpOw0KKwlzdHJzY3B5 KGNhcC0+ZHJpdmVyLCBNVEtfSlBFR19OQU1FLCBzaXplb2YoY2FwLT5kcml2ZXIpKTsNCiAJc3Ry c2NweShjYXAtPmNhcmQsIE1US19KUEVHX05BTUUgIiBkZWNvZGVyIiwgc2l6ZW9mKGNhcC0+Y2Fy ZCkpOw0KIAlzbnByaW50ZihjYXAtPmJ1c19pbmZvLCBzaXplb2YoY2FwLT5idXNfaW5mbyksICJw bGF0Zm9ybTolcyIsDQogCQkgZGV2X25hbWUoanBlZy0+ZGV2KSk7DQpAQCAtOTQsNiArMTYzLDU0 IEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfcXVlcnljYXAoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQg KnByaXYsDQogCXJldHVybiAwOw0KIH0NCiANCitzdGF0aWMgaW50IHZpZGlvY19qcGVnX2VuY19z X2N0cmwoc3RydWN0IHY0bDJfY3RybCAqY3RybCkNCit7DQorCXN0cnVjdCBtdGtfanBlZ19jdHgg KmN0eCA9IGN0cmxfdG9fY3R4KGN0cmwpOw0KKw0KKwlzd2l0Y2ggKGN0cmwtPmlkKSB7DQorCWNh c2UgVjRMMl9DSURfSlBFR19SRVNUQVJUX0lOVEVSVkFMOg0KKwkJY3R4LT5yZXN0YXJ0X2ludGVy dmFsID0gY3RybC0+dmFsOw0KKwkJYnJlYWs7DQorCWNhc2UgVjRMMl9DSURfSlBFR19DT01QUkVT U0lPTl9RVUFMSVRZOg0KKwkJY3R4LT5lbmNfcXVhbGl0eSA9IGN0cmwtPnZhbDsNCisJCWJyZWFr Ow0KKwljYXNlIFY0TDJfQ0lEX0pQRUdfQUNUSVZFX01BUktFUjoNCisJCWN0eC0+ZW5hYmxlX2V4 aWYgPSBjdHJsLT52YWwgJiBWNEwyX0pQRUdfQUNUSVZFX01BUktFUl9BUFAxID8NCisJCQkJICAg dHJ1ZSA6IGZhbHNlOw0KKwkJYnJlYWs7DQorCX0NCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0 YXRpYyBjb25zdCBzdHJ1Y3QgdjRsMl9jdHJsX29wcyBtdGtfanBlZ19lbmNfY3RybF9vcHMgPSB7 DQorCS5zX2N0cmwgPSB2aWRpb2NfanBlZ19lbmNfc19jdHJsLA0KK307DQorDQorc3RhdGljIGlu dCBtdGtfanBlZ19lbmNfY3RybHNfc2V0dXAoc3RydWN0IG10a19qcGVnX2N0eCAqY3R4KQ0KK3sN CisJY29uc3Qgc3RydWN0IHY0bDJfY3RybF9vcHMgKm9wcyA9ICZtdGtfanBlZ19lbmNfY3RybF9v cHM7DQorCXN0cnVjdCB2NGwyX2N0cmxfaGFuZGxlciAqaGFuZGxlciA9ICZjdHgtPmN0cmxfaGRs Ow0KKw0KKwl2NGwyX2N0cmxfaGFuZGxlcl9pbml0KGhhbmRsZXIsIDMpOw0KKw0KKwl2NGwyX2N0 cmxfbmV3X3N0ZChoYW5kbGVyLCBvcHMsIFY0TDJfQ0lEX0pQRUdfUkVTVEFSVF9JTlRFUlZBTCwg MCwgMTAwLA0KKwkJCSAgMSwgMCk7DQorCXY0bDJfY3RybF9uZXdfc3RkKGhhbmRsZXIsIG9wcywg VjRMMl9DSURfSlBFR19DT01QUkVTU0lPTl9RVUFMSVRZLCA0OCwNCisJCQkgIDEwMCwgMSwgOTAp Ow0KKwl2NGwyX2N0cmxfbmV3X3N0ZChoYW5kbGVyLCBvcHMsIFY0TDJfQ0lEX0pQRUdfQUNUSVZF X01BUktFUiwgMCwNCisJCQkgIFY0TDJfSlBFR19BQ1RJVkVfTUFSS0VSX0FQUDEsIDAsIDApOw0K Kw0KKwlpZiAoaGFuZGxlci0+ZXJyb3IpIHsNCisJCXY0bDJfY3RybF9oYW5kbGVyX2ZyZWUoJmN0 eC0+Y3RybF9oZGwpOw0KKwkJcmV0dXJuIGhhbmRsZXItPmVycm9yOw0KKwl9DQorDQorCXY0bDJf Y3RybF9oYW5kbGVyX3NldHVwKCZjdHgtPmN0cmxfaGRsKTsNCisNCisJcmV0dXJuIDA7DQorfQ0K Kw0KIHN0YXRpYyBpbnQgbXRrX2pwZWdfZW51bV9mbXQoc3RydWN0IG10a19qcGVnX2ZtdCAqbXRr X2pwZWdfZm9ybWF0cywgaW50IG4sDQogCQkJICAgICBzdHJ1Y3QgdjRsMl9mbXRkZXNjICpmLCB1 MzIgdHlwZSkNCiB7DQpAQCAtMTE1LDExNyArMjMyLDEwNSBAQCBzdGF0aWMgaW50IG10a19qcGVn X2VudW1fZm10KHN0cnVjdCBtdGtfanBlZ19mbXQgKm10a19qcGVnX2Zvcm1hdHMsIGludCBuLA0K IAlyZXR1cm4gMDsNCiB9DQogDQotc3RhdGljIGludCBtdGtfanBlZ19lbnVtX2ZtdF92aWRfY2Fw KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KLQkJCQkgICAgIHN0cnVjdCB2NGwyX2Zt dGRlc2MgKmYpDQorc3RhdGljIGludCBtdGtfanBlZ19lbmNfZW51bV9mbXRfdmlkX2NhcChzdHJ1 Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCisJCQkJCSBzdHJ1Y3QgdjRsMl9mbXRkZXNjICpm KQ0KIHsNCi0JcmV0dXJuIG10a19qcGVnX2VudW1fZm10KG10a19qcGVnX2Zvcm1hdHMsIE1US19K UEVHX05VTV9GT1JNQVRTLCBmLA0KKwlyZXR1cm4gbXRrX2pwZWdfZW51bV9mbXQobXRrX2pwZWdf ZW5jX2Zvcm1hdHMsDQorCQkJCSBNVEtfSlBFR19FTkNfTlVNX0ZPUk1BVFMsIGYsDQorCQkJCSBN VEtfSlBFR19GTVRfRkxBR19FTkNfQ0FQVFVSRSk7DQorfQ0KKw0KK3N0YXRpYyBpbnQgbXRrX2pw ZWdfZGVjX2VudW1fZm10X3ZpZF9jYXAoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQor CQkJCQkgc3RydWN0IHY0bDJfZm10ZGVzYyAqZikNCit7DQorCXJldHVybiBtdGtfanBlZ19lbnVt X2ZtdChtdGtfanBlZ19kZWNfZm9ybWF0cywNCisJCQkJIE1US19KUEVHX0RFQ19OVU1fRk9STUFU UywgZiwNCiAJCQkJIE1US19KUEVHX0ZNVF9GTEFHX0RFQ19DQVBUVVJFKTsNCiB9DQogDQotc3Rh dGljIGludCBtdGtfanBlZ19lbnVtX2ZtdF92aWRfb3V0KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lk ICpwcml2LA0KLQkJCQkgICAgIHN0cnVjdCB2NGwyX2ZtdGRlc2MgKmYpDQorc3RhdGljIGludCBt dGtfanBlZ19lbmNfZW51bV9mbXRfdmlkX291dChzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJp diwNCisJCQkJCSBzdHJ1Y3QgdjRsMl9mbXRkZXNjICpmKQ0KK3sNCisJcmV0dXJuIG10a19qcGVn X2VudW1fZm10KG10a19qcGVnX2VuY19mb3JtYXRzLA0KKwkJCQkgTVRLX0pQRUdfRU5DX05VTV9G T1JNQVRTLCBmLA0KKwkJCQkgTVRLX0pQRUdfRk1UX0ZMQUdfRU5DX09VVFBVVCk7DQorfQ0KKw0K K3N0YXRpYyBpbnQgbXRrX2pwZWdfZGVjX2VudW1fZm10X3ZpZF9vdXQoc3RydWN0IGZpbGUgKmZp bGUsIHZvaWQgKnByaXYsDQorCQkJCQkgc3RydWN0IHY0bDJfZm10ZGVzYyAqZikNCiB7DQotCXJl dHVybiBtdGtfanBlZ19lbnVtX2ZtdChtdGtfanBlZ19mb3JtYXRzLCBNVEtfSlBFR19OVU1fRk9S TUFUUywgZiwNCi0JCQkJIE1US19KUEVHX0ZNVF9GTEFHX0RFQ19PVVRQVVQpOw0KKwlyZXR1cm4g bXRrX2pwZWdfZW51bV9mbXQobXRrX2pwZWdfZGVjX2Zvcm1hdHMsIE1US19KUEVHX0RFQ19OVU1f Rk9STUFUUywNCisJCQkJIGYsIE1US19KUEVHX0ZNVF9GTEFHX0RFQ19PVVRQVVQpOw0KIH0NCiAN Ci1zdGF0aWMgc3RydWN0IG10a19qcGVnX3FfZGF0YSAqbXRrX2pwZWdfZ2V0X3FfZGF0YShzdHJ1 Y3QgbXRrX2pwZWdfY3R4ICpjdHgsDQotCQkJCQkJICAgZW51bSB2NGwyX2J1Zl90eXBlIHR5cGUp DQorc3RhdGljIHN0cnVjdCBtdGtfanBlZ19xX2RhdGEgKg0KK210a19qcGVnX2dldF9xX2RhdGEo c3RydWN0IG10a19qcGVnX2N0eCAqY3R4LCBlbnVtIHY0bDJfYnVmX3R5cGUgdHlwZSkNCiB7DQog CWlmIChWNEwyX1RZUEVfSVNfT1VUUFVUKHR5cGUpKQ0KIAkJcmV0dXJuICZjdHgtPm91dF9xOw0K IAlyZXR1cm4gJmN0eC0+Y2FwX3E7DQogfQ0KIA0KLXN0YXRpYyBzdHJ1Y3QgbXRrX2pwZWdfZm10 ICptdGtfanBlZ19maW5kX2Zvcm1hdChzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsDQotCQkJCQkJ IHUzMiBwaXhlbGZvcm1hdCwNCitzdGF0aWMgc3RydWN0IG10a19qcGVnX2ZtdCAqbXRrX2pwZWdf ZmluZF9mb3JtYXQodTMyIHBpeGVsZm9ybWF0LA0KIAkJCQkJCSB1bnNpZ25lZCBpbnQgZm10X3R5 cGUpDQogew0KLQl1bnNpZ25lZCBpbnQgaywgZm10X2ZsYWc7DQotDQotCWZtdF9mbGFnID0gKGZt dF90eXBlID09IE1US19KUEVHX0ZNVF9UWVBFX09VVFBVVCkgPw0KLQkJICAgTVRLX0pQRUdfRk1U X0ZMQUdfREVDX09VVFBVVCA6DQotCQkgICBNVEtfSlBFR19GTVRfRkxBR19ERUNfQ0FQVFVSRTsN CisJdW5zaWduZWQgaW50IGs7DQorCXN0cnVjdCBtdGtfanBlZ19mbXQgKmZtdDsNCiANCi0JZm9y IChrID0gMDsgayA8IE1US19KUEVHX05VTV9GT1JNQVRTOyBrKyspIHsNCi0JCXN0cnVjdCBtdGtf anBlZ19mbXQgKmZtdCA9ICZtdGtfanBlZ19mb3JtYXRzW2tdOw0KKwlmb3IgKGsgPSAwOyBrIDwg TVRLX0pQRUdfRU5DX05VTV9GT1JNQVRTOyBrKyspIHsNCisJCWZtdCA9ICZtdGtfanBlZ19lbmNf Zm9ybWF0c1trXTsNCiANCi0JCWlmIChmbXQtPmZvdXJjYyA9PSBwaXhlbGZvcm1hdCAmJiBmbXQt PmZsYWdzICYgZm10X2ZsYWcpDQorCQlpZiAoZm10LT5mb3VyY2MgPT0gcGl4ZWxmb3JtYXQgJiYg Zm10LT5mbGFncyAmIGZtdF90eXBlKQ0KIAkJCXJldHVybiBmbXQ7DQogCX0NCiANCi0JcmV0dXJu IE5VTEw7DQotfQ0KKwlmb3IgKGsgPSAwOyBrIDwgTVRLX0pQRUdfREVDX05VTV9GT1JNQVRTOyBr KyspIHsNCisJCWZtdCA9ICZtdGtfanBlZ19kZWNfZm9ybWF0c1trXTsNCiANCi1zdGF0aWMgdm9p ZCBtdGtfanBlZ19hZGp1c3RfZm10X21wbGFuZShzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsDQot CQkJCSAgICAgICBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQotew0KLQlzdHJ1Y3QgdjRsMl9waXhf Zm9ybWF0X21wbGFuZSAqcGl4X21wID0gJmYtPmZtdC5waXhfbXA7DQotCXN0cnVjdCBtdGtfanBl Z19xX2RhdGEgKnFfZGF0YTsNCi0JaW50IGk7DQotDQotCXFfZGF0YSA9IG10a19qcGVnX2dldF9x X2RhdGEoY3R4LCBmLT50eXBlKTsNCi0NCi0JcGl4X21wLT53aWR0aCA9IHFfZGF0YS0+dzsNCi0J cGl4X21wLT5oZWlnaHQgPSBxX2RhdGEtPmg7DQotCXBpeF9tcC0+cGl4ZWxmb3JtYXQgPSBxX2Rh dGEtPmZtdC0+Zm91cmNjOw0KLQlwaXhfbXAtPm51bV9wbGFuZXMgPSBxX2RhdGEtPmZtdC0+Y29s cGxhbmVzOw0KLQ0KLQlmb3IgKGkgPSAwOyBpIDwgcGl4X21wLT5udW1fcGxhbmVzOyBpKyspIHsN Ci0JCXBpeF9tcC0+cGxhbmVfZm10W2ldLmJ5dGVzcGVybGluZSA9IHFfZGF0YS0+Ynl0ZXNwZXJs aW5lW2ldOw0KLQkJcGl4X21wLT5wbGFuZV9mbXRbaV0uc2l6ZWltYWdlID0gcV9kYXRhLT5zaXpl aW1hZ2VbaV07DQorCQlpZiAoZm10LT5mb3VyY2MgPT0gcGl4ZWxmb3JtYXQgJiYgZm10LT5mbGFn cyAmIGZtdF90eXBlKQ0KKwkJCXJldHVybiBmbXQ7DQogCX0NCisNCisJcmV0dXJuIE5VTEw7DQog fQ0KIA0KLXN0YXRpYyBpbnQgbXRrX2pwZWdfdHJ5X2ZtdF9tcGxhbmUoc3RydWN0IHY0bDJfZm9y bWF0ICpmLA0KLQkJCQkgICBzdHJ1Y3QgbXRrX2pwZWdfZm10ICpmbXQsDQotCQkJCSAgIHN0cnVj dCBtdGtfanBlZ19jdHggKmN0eCwgaW50IHFfdHlwZSkNCitzdGF0aWMgaW50IHZpZGlvY190cnlf Zm10KHN0cnVjdCB2NGwyX2Zvcm1hdCAqZiwgc3RydWN0IG10a19qcGVnX2ZtdCAqZm10KQ0KIHsN CiAJc3RydWN0IHY0bDJfcGl4X2Zvcm1hdF9tcGxhbmUgKnBpeF9tcCA9ICZmLT5mbXQucGl4X21w Ow0KIAlpbnQgaTsNCiANCi0JbWVtc2V0KHBpeF9tcC0+cmVzZXJ2ZWQsIDAsIHNpemVvZihwaXhf bXAtPnJlc2VydmVkKSk7DQogCXBpeF9tcC0+ZmllbGQgPSBWNEwyX0ZJRUxEX05PTkU7DQotDQot CWlmIChjdHgtPnN0YXRlICE9IE1US19KUEVHX0lOSVQpIHsNCi0JCW10a19qcGVnX2FkanVzdF9m bXRfbXBsYW5lKGN0eCwgZik7DQotCQlyZXR1cm4gMDsNCi0JfQ0KLQ0KIAlwaXhfbXAtPm51bV9w bGFuZXMgPSBmbXQtPmNvbHBsYW5lczsNCiAJcGl4X21wLT5waXhlbGZvcm1hdCA9IGZtdC0+Zm91 cmNjOw0KIA0KLQlpZiAocV90eXBlID09IE1US19KUEVHX0ZNVF9UWVBFX09VVFBVVCkgew0KLQkJ c3RydWN0IHY0bDJfcGxhbmVfcGl4X2Zvcm1hdCAqcGZtdCA9ICZwaXhfbXAtPnBsYW5lX2ZtdFsw XTsNCi0NCisJaWYgKGZtdC0+Zm91cmNjID09IFY0TDJfUElYX0ZNVF9KUEVHKSB7DQogCQlwaXhf bXAtPmhlaWdodCA9IGNsYW1wKHBpeF9tcC0+aGVpZ2h0LCBNVEtfSlBFR19NSU5fSEVJR0hULA0K IAkJCQkgICAgICAgTVRLX0pQRUdfTUFYX0hFSUdIVCk7DQogCQlwaXhfbXAtPndpZHRoID0gY2xh bXAocGl4X21wLT53aWR0aCwgTVRLX0pQRUdfTUlOX1dJRFRILA0KIAkJCQkgICAgICBNVEtfSlBF R19NQVhfV0lEVEgpOw0KLQ0KLQkJbWVtc2V0KHBmbXQtPnJlc2VydmVkLCAwLCBzaXplb2YocGZt dC0+cmVzZXJ2ZWQpKTsNCi0JCXBmbXQtPmJ5dGVzcGVybGluZSA9IDA7DQotCQkvKiBTb3VyY2Ug c2l6ZSBtdXN0IGJlIGFsaWduZWQgdG8gMTI4ICovDQotCQlwZm10LT5zaXplaW1hZ2UgPSByb3Vu ZF91cChwZm10LT5zaXplaW1hZ2UsIDEyOCk7DQotCQlpZiAocGZtdC0+c2l6ZWltYWdlID09IDAp DQotCQkJcGZtdC0+c2l6ZWltYWdlID0gTVRLX0pQRUdfREVGQVVMVF9TSVpFSU1BR0U7DQotCQly ZXR1cm4gMDsNCisJCXBpeF9tcC0+cGxhbmVfZm10WzBdLmJ5dGVzcGVybGluZSA9IDA7DQorCQlw aXhfbXAtPnBsYW5lX2ZtdFswXS5zaXplaW1hZ2UgPQ0KKwkJCQlyb3VuZF91cChwaXhfbXAtPnBs YW5lX2ZtdFswXS5zaXplaW1hZ2UsIDEyOCk7DQorCQlpZiAocGl4X21wLT5wbGFuZV9mbXRbMF0u c2l6ZWltYWdlID09IDApDQorCQkJcGl4X21wLT5wbGFuZV9mbXRbMF0uc2l6ZWltYWdlID0NCisJ CQkJTVRLX0pQRUdfREVGQVVMVF9TSVpFSU1BR0U7DQorCX0gZWxzZSB7DQorCQlwaXhfbXAtPmhl aWdodCA9IGNsYW1wKHJvdW5kX3VwKHBpeF9tcC0+aGVpZ2h0LCBmbXQtPnZfYWxpZ24pLA0KKwkJ CQkgICAgICAgTVRLX0pQRUdfTUlOX0hFSUdIVCwNCisJCQkJICAgICAgIE1US19KUEVHX01BWF9I RUlHSFQpOw0KKwkJcGl4X21wLT53aWR0aCA9IGNsYW1wKHJvdW5kX3VwKHBpeF9tcC0+d2lkdGgs IGZtdC0+aF9hbGlnbiksDQorCQkJCSAgICAgIE1US19KUEVHX01JTl9XSURUSCwgTVRLX0pQRUdf TUFYX1dJRFRIKTsNCisJCWZvciAoaSA9IDA7IGkgPCBwaXhfbXAtPm51bV9wbGFuZXM7IGkrKykg ew0KKwkJCXN0cnVjdCB2NGwyX3BsYW5lX3BpeF9mb3JtYXQgKnBmbXQgPQ0KKwkJCQkJCQkmcGl4 X21wLT5wbGFuZV9mbXRbaV07DQorCQkJdTMyIHN0cmlkZSA9IHBpeF9tcC0+d2lkdGggKiBmbXQt Pmhfc2FtcGxlW2ldIC8gNDsNCisJCQl1MzIgaCA9IHBpeF9tcC0+aGVpZ2h0ICogZm10LT52X3Nh bXBsZVtpXSAvIDQ7DQorDQorCQkJcGZtdC0+Ynl0ZXNwZXJsaW5lID0gc3RyaWRlOw0KKwkJCXBm bXQtPnNpemVpbWFnZSA9IHN0cmlkZSAqIGg7DQorCQl9DQogCX0NCiANCi0JLyogdHlwZSBpcyBN VEtfSlBFR19GTVRfVFlQRV9DQVBUVVJFICovDQotCXBpeF9tcC0+aGVpZ2h0ID0gY2xhbXAocm91 bmRfdXAocGl4X21wLT5oZWlnaHQsIGZtdC0+dl9hbGlnbiksDQotCQkJICAgICAgIE1US19KUEVH X01JTl9IRUlHSFQsIE1US19KUEVHX01BWF9IRUlHSFQpOw0KLQlwaXhfbXAtPndpZHRoID0gY2xh bXAocm91bmRfdXAocGl4X21wLT53aWR0aCwgZm10LT5oX2FsaWduKSwNCi0JCQkgICAgICBNVEtf SlBFR19NSU5fV0lEVEgsIE1US19KUEVHX01BWF9XSURUSCk7DQotDQotCWZvciAoaSA9IDA7IGkg PCBmbXQtPmNvbHBsYW5lczsgaSsrKSB7DQotCQlzdHJ1Y3QgdjRsMl9wbGFuZV9waXhfZm9ybWF0 ICpwZm10ID0gJnBpeF9tcC0+cGxhbmVfZm10W2ldOw0KLQkJdTMyIHN0cmlkZSA9IHBpeF9tcC0+ d2lkdGggKiBmbXQtPmhfc2FtcGxlW2ldIC8gNDsNCi0JCXUzMiBoID0gcGl4X21wLT5oZWlnaHQg KiBmbXQtPnZfc2FtcGxlW2ldIC8gNDsNCi0NCi0JCXBmbXQtPmJ5dGVzcGVybGluZSA9IHN0cmlk ZTsNCi0JCXBmbXQtPnNpemVpbWFnZSA9IHN0cmlkZSAqIGg7DQotCX0NCiAJcmV0dXJuIDA7DQog fQ0KIA0KQEAgLTI4MCwxNCArMzg1LDM1IEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfZ19mbXRfdmlk X21wbGFuZShzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCiAJcmV0dXJuIDA7DQogfQ0K IA0KLXN0YXRpYyBpbnQgbXRrX2pwZWdfdHJ5X2ZtdF92aWRfY2FwX21wbGFuZShzdHJ1Y3QgZmls ZSAqZmlsZSwgdm9pZCAqcHJpdiwNCi0JCQkJCSAgIHN0cnVjdCB2NGwyX2Zvcm1hdCAqZikNCitz dGF0aWMgaW50IG10a19qcGVnX2VuY190cnlfZm10X3ZpZF9jYXBfbXBsYW5lKHN0cnVjdCBmaWxl ICpmaWxlLCB2b2lkICpwcml2LA0KKwkJCQkJICAgICAgIHN0cnVjdCB2NGwyX2Zvcm1hdCAqZikN Cit7DQorCXN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IG10a19qcGVnX2ZoX3RvX2N0eChwcml2 KTsNCisJc3RydWN0IG10a19qcGVnX2ZtdCAqZm10Ow0KKw0KKwlmbXQgPSBtdGtfanBlZ19maW5k X2Zvcm1hdChmLT5mbXQucGl4X21wLnBpeGVsZm9ybWF0LA0KKwkJCQkgICBNVEtfSlBFR19GTVRf RkxBR19FTkNfQ0FQVFVSRSk7DQorCWlmICghZm10KQ0KKwkJZm10ID0gY3R4LT5jYXBfcS5mbXQ7 DQorDQorCXY0bDJfZGJnKDIsIGRlYnVnLCAmY3R4LT5qcGVnLT52NGwyX2RldiwgIiglZCkgdHJ5 X2ZtdDolYyVjJWMlY1xuIiwNCisJCSBmLT50eXBlLA0KKwkJIChmbXQtPmZvdXJjYyAmIDB4ZmYp LA0KKwkJIChmbXQtPmZvdXJjYyA+PiAgOCAmIDB4ZmYpLA0KKwkJIChmbXQtPmZvdXJjYyA+PiAx NiAmIDB4ZmYpLA0KKwkJIChmbXQtPmZvdXJjYyA+PiAyNCAmIDB4ZmYpKTsNCisNCisJcmV0dXJu IHZpZGlvY190cnlfZm10KGYsIGZtdCk7DQorfQ0KKw0KK3N0YXRpYyBpbnQgbXRrX2pwZWdfZGVj X3RyeV9mbXRfdmlkX2NhcF9tcGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQor CQkJCQkgICAgICAgc3RydWN0IHY0bDJfZm9ybWF0ICpmKQ0KIHsNCiAJc3RydWN0IG10a19qcGVn X2N0eCAqY3R4ID0gbXRrX2pwZWdfZmhfdG9fY3R4KHByaXYpOw0KIAlzdHJ1Y3QgbXRrX2pwZWdf Zm10ICpmbXQ7DQogDQotCWZtdCA9IG10a19qcGVnX2ZpbmRfZm9ybWF0KGN0eCwgZi0+Zm10LnBp eF9tcC5waXhlbGZvcm1hdCwNCi0JCQkJICAgTVRLX0pQRUdfRk1UX1RZUEVfQ0FQVFVSRSk7DQor CWZtdCA9IG10a19qcGVnX2ZpbmRfZm9ybWF0KGYtPmZtdC5waXhfbXAucGl4ZWxmb3JtYXQsDQor CQkJCSAgIE1US19KUEVHX0ZNVF9GTEFHX0RFQ19DQVBUVVJFKTsNCiAJaWYgKCFmbXQpDQogCQlm bXQgPSBjdHgtPmNhcF9xLmZtdDsNCiANCkBAIC0yOTgsMTcgKzQyNCw0MyBAQCBzdGF0aWMgaW50 IG10a19qcGVnX3RyeV9mbXRfdmlkX2NhcF9tcGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQg KnByaXYsDQogCQkgKGZtdC0+Zm91cmNjID4+IDE2ICYgMHhmZiksDQogCQkgKGZtdC0+Zm91cmNj ID4+IDI0ICYgMHhmZikpOw0KIA0KLQlyZXR1cm4gbXRrX2pwZWdfdHJ5X2ZtdF9tcGxhbmUoZiwg Zm10LCBjdHgsIE1US19KUEVHX0ZNVF9UWVBFX0NBUFRVUkUpOw0KKwlpZiAoY3R4LT5zdGF0ZSAh PSBNVEtfSlBFR19JTklUKSB7DQorCQltdGtfanBlZ19nX2ZtdF92aWRfbXBsYW5lKGZpbGUsIHBy aXYsIGYpOw0KKwkJcmV0dXJuIDA7DQorCX0NCisNCisJcmV0dXJuIHZpZGlvY190cnlfZm10KGYs IGZtdCk7DQorfQ0KKw0KK3N0YXRpYyBpbnQgbXRrX2pwZWdfZW5jX3RyeV9mbXRfdmlkX291dF9t cGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQorCQkJCQkgICAgICAgc3RydWN0 IHY0bDJfZm9ybWF0ICpmKQ0KK3sNCisJc3RydWN0IG10a19qcGVnX2N0eCAqY3R4ID0gbXRrX2pw ZWdfZmhfdG9fY3R4KHByaXYpOw0KKwlzdHJ1Y3QgbXRrX2pwZWdfZm10ICpmbXQ7DQorDQorCWZt dCA9IG10a19qcGVnX2ZpbmRfZm9ybWF0KGYtPmZtdC5waXhfbXAucGl4ZWxmb3JtYXQsDQorCQkJ CSAgIE1US19KUEVHX0ZNVF9GTEFHX0VOQ19PVVRQVVQpOw0KKwlpZiAoIWZtdCkNCisJCWZtdCA9 IGN0eC0+b3V0X3EuZm10Ow0KKw0KKwl2NGwyX2RiZygyLCBkZWJ1ZywgJmN0eC0+anBlZy0+djRs Ml9kZXYsICIoJWQpIHRyeV9mbXQ6JWMlYyVjJWNcbiIsDQorCQkgZi0+dHlwZSwNCisJCSAoZm10 LT5mb3VyY2MgJiAweGZmKSwNCisJCSAoZm10LT5mb3VyY2MgPj4gIDggJiAweGZmKSwNCisJCSAo Zm10LT5mb3VyY2MgPj4gMTYgJiAweGZmKSwNCisJCSAoZm10LT5mb3VyY2MgPj4gMjQgJiAweGZm KSk7DQorDQorCXJldHVybiB2aWRpb2NfdHJ5X2ZtdChmLCBmbXQpOw0KIH0NCiANCi1zdGF0aWMg aW50IG10a19qcGVnX3RyeV9mbXRfdmlkX291dF9tcGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZv aWQgKnByaXYsDQotCQkJCQkgICBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQorc3RhdGljIGludCBt dGtfanBlZ19kZWNfdHJ5X2ZtdF92aWRfb3V0X21wbGFuZShzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9p ZCAqcHJpdiwNCisJCQkJCSAgICAgICBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQogew0KIAlzdHJ1 Y3QgbXRrX2pwZWdfY3R4ICpjdHggPSBtdGtfanBlZ19maF90b19jdHgocHJpdik7DQogCXN0cnVj dCBtdGtfanBlZ19mbXQgKmZtdDsNCiANCi0JZm10ID0gbXRrX2pwZWdfZmluZF9mb3JtYXQoY3R4 LCBmLT5mbXQucGl4X21wLnBpeGVsZm9ybWF0LA0KLQkJCQkgICBNVEtfSlBFR19GTVRfVFlQRV9P VVRQVVQpOw0KKwlmbXQgPSBtdGtfanBlZ19maW5kX2Zvcm1hdChmLT5mbXQucGl4X21wLnBpeGVs Zm9ybWF0LA0KKwkJCQkgICBNVEtfSlBFR19GTVRfRkxBR19ERUNfT1VUUFVUKTsNCiAJaWYgKCFm bXQpDQogCQlmbXQgPSBjdHgtPm91dF9xLmZtdDsNCiANCkBAIC0zMTksMTcgKzQ3MSwyMSBAQCBz dGF0aWMgaW50IG10a19qcGVnX3RyeV9mbXRfdmlkX291dF9tcGxhbmUoc3RydWN0IGZpbGUgKmZp bGUsIHZvaWQgKnByaXYsDQogCQkgKGZtdC0+Zm91cmNjID4+IDE2ICYgMHhmZiksDQogCQkgKGZt dC0+Zm91cmNjID4+IDI0ICYgMHhmZikpOw0KIA0KLQlyZXR1cm4gbXRrX2pwZWdfdHJ5X2ZtdF9t cGxhbmUoZiwgZm10LCBjdHgsIE1US19KUEVHX0ZNVF9UWVBFX09VVFBVVCk7DQorCWlmIChjdHgt PnN0YXRlICE9IE1US19KUEVHX0lOSVQpIHsNCisJCW10a19qcGVnX2dfZm10X3ZpZF9tcGxhbmUo ZmlsZSwgcHJpdiwgZik7DQorCQlyZXR1cm4gMDsNCisJfQ0KKw0KKwlyZXR1cm4gdmlkaW9jX3Ry eV9mbXQoZiwgZm10KTsNCiB9DQogDQogc3RhdGljIGludCBtdGtfanBlZ19zX2ZtdF9tcGxhbmUo c3RydWN0IG10a19qcGVnX2N0eCAqY3R4LA0KLQkJCQkgc3RydWN0IHY0bDJfZm9ybWF0ICpmKQ0K KwkJCQkgc3RydWN0IHY0bDJfZm9ybWF0ICpmLCB1bnNpZ25lZCBpbnQgZm10X3R5cGUpDQogew0K IAlzdHJ1Y3QgdmIyX3F1ZXVlICp2cTsNCiAJc3RydWN0IG10a19qcGVnX3FfZGF0YSAqcV9kYXRh ID0gTlVMTDsNCiAJc3RydWN0IHY0bDJfcGl4X2Zvcm1hdF9tcGxhbmUgKnBpeF9tcCA9ICZmLT5m bXQucGl4X21wOw0KIAlzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpqcGVnID0gY3R4LT5qcGVnOw0KLQl1 bnNpZ25lZCBpbnQgZl90eXBlOw0KIAlpbnQgaTsNCiANCiAJdnEgPSB2NGwyX20ybV9nZXRfdnEo Y3R4LT5maC5tMm1fY3R4LCBmLT50eXBlKTsNCkBAIC0zNDMsMTAgKzQ5OSw3IEBAIHN0YXRpYyBp bnQgbXRrX2pwZWdfc19mbXRfbXBsYW5lKHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCwNCiAJCXJl dHVybiAtRUJVU1k7DQogCX0NCiANCi0JZl90eXBlID0gVjRMMl9UWVBFX0lTX09VVFBVVChmLT50 eXBlKSA/DQotCQkJIE1US19KUEVHX0ZNVF9UWVBFX09VVFBVVCA6IE1US19KUEVHX0ZNVF9UWVBF X0NBUFRVUkU7DQotDQotCXFfZGF0YS0+Zm10ID0gbXRrX2pwZWdfZmluZF9mb3JtYXQoY3R4LCBw aXhfbXAtPnBpeGVsZm9ybWF0LCBmX3R5cGUpOw0KKwlxX2RhdGEtPmZtdCA9IG10a19qcGVnX2Zp bmRfZm9ybWF0KHBpeF9tcC0+cGl4ZWxmb3JtYXQsIGZtdF90eXBlKTsNCiAJcV9kYXRhLT53ID0g cGl4X21wLT53aWR0aDsNCiAJcV9kYXRhLT5oID0gcGl4X21wLT5oZWlnaHQ7DQogCWN0eC0+Y29s b3JzcGFjZSA9IHBpeF9tcC0+Y29sb3JzcGFjZTsNCkBAIC0zNzQsMjggKzUyNyw1NiBAQCBzdGF0 aWMgaW50IG10a19qcGVnX3NfZm10X21wbGFuZShzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsDQog CXJldHVybiAwOw0KIH0NCiANCi1zdGF0aWMgaW50IG10a19qcGVnX3NfZm10X3ZpZF9vdXRfbXBs YW5lKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KLQkJCQkJIHN0cnVjdCB2NGwyX2Zv cm1hdCAqZikNCitzdGF0aWMgaW50IG10a19qcGVnX2VuY19zX2ZtdF92aWRfb3V0X21wbGFuZShz dHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCisJCQkJCSAgICAgc3RydWN0IHY0bDJfZm9y bWF0ICpmKQ0KK3sNCisJaW50IHJldDsNCisNCisJcmV0ID0gbXRrX2pwZWdfZW5jX3RyeV9mbXRf dmlkX291dF9tcGxhbmUoZmlsZSwgcHJpdiwgZik7DQorCWlmIChyZXQpDQorCQlyZXR1cm4gcmV0 Ow0KKw0KKwlyZXR1cm4gbXRrX2pwZWdfc19mbXRfbXBsYW5lKG10a19qcGVnX2ZoX3RvX2N0eChw cml2KSwgZiwNCisJCQkJICAgICBNVEtfSlBFR19GTVRfRkxBR19FTkNfT1VUUFVUKTsNCit9DQor DQorc3RhdGljIGludCBtdGtfanBlZ19kZWNfc19mbXRfdmlkX291dF9tcGxhbmUoc3RydWN0IGZp bGUgKmZpbGUsIHZvaWQgKnByaXYsDQorCQkJCQkgICAgIHN0cnVjdCB2NGwyX2Zvcm1hdCAqZikN CiB7DQogCWludCByZXQ7DQogDQotCXJldCA9IG10a19qcGVnX3RyeV9mbXRfdmlkX291dF9tcGxh bmUoZmlsZSwgcHJpdiwgZik7DQorCXJldCA9IG10a19qcGVnX2RlY190cnlfZm10X3ZpZF9vdXRf bXBsYW5lKGZpbGUsIHByaXYsIGYpOw0KIAlpZiAocmV0KQ0KIAkJcmV0dXJuIHJldDsNCiANCi0J cmV0dXJuIG10a19qcGVnX3NfZm10X21wbGFuZShtdGtfanBlZ19maF90b19jdHgocHJpdiksIGYp Ow0KKwlyZXR1cm4gbXRrX2pwZWdfc19mbXRfbXBsYW5lKG10a19qcGVnX2ZoX3RvX2N0eChwcml2 KSwgZiwNCisJCQkJICAgICBNVEtfSlBFR19GTVRfRkxBR19ERUNfT1VUUFVUKTsNCiB9DQogDQot c3RhdGljIGludCBtdGtfanBlZ19zX2ZtdF92aWRfY2FwX21wbGFuZShzdHJ1Y3QgZmlsZSAqZmls ZSwgdm9pZCAqcHJpdiwNCi0JCQkJCSBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQorc3RhdGljIGlu dCBtdGtfanBlZ19lbmNfc19mbXRfdmlkX2NhcF9tcGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZv aWQgKnByaXYsDQorCQkJCQkgICAgIHN0cnVjdCB2NGwyX2Zvcm1hdCAqZikNCiB7DQogCWludCBy ZXQ7DQogDQotCXJldCA9IG10a19qcGVnX3RyeV9mbXRfdmlkX2NhcF9tcGxhbmUoZmlsZSwgcHJp diwgZik7DQorCXJldCA9IG10a19qcGVnX2VuY190cnlfZm10X3ZpZF9jYXBfbXBsYW5lKGZpbGUs IHByaXYsIGYpOw0KIAlpZiAocmV0KQ0KIAkJcmV0dXJuIHJldDsNCiANCi0JcmV0dXJuIG10a19q cGVnX3NfZm10X21wbGFuZShtdGtfanBlZ19maF90b19jdHgocHJpdiksIGYpOw0KKwlyZXR1cm4g bXRrX2pwZWdfc19mbXRfbXBsYW5lKG10a19qcGVnX2ZoX3RvX2N0eChwcml2KSwgZiwNCisJCQkJ ICAgICBNVEtfSlBFR19GTVRfRkxBR19FTkNfQ0FQVFVSRSk7DQorfQ0KKw0KK3N0YXRpYyBpbnQg bXRrX2pwZWdfZGVjX3NfZm10X3ZpZF9jYXBfbXBsYW5lKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lk ICpwcml2LA0KKwkJCQkJICAgICBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQorew0KKwlpbnQgcmV0 Ow0KKw0KKwlyZXQgPSBtdGtfanBlZ19kZWNfdHJ5X2ZtdF92aWRfY2FwX21wbGFuZShmaWxlLCBw cml2LCBmKTsNCisJaWYgKHJldCkNCisJCXJldHVybiByZXQ7DQorDQorCXJldHVybiBtdGtfanBl Z19zX2ZtdF9tcGxhbmUobXRrX2pwZWdfZmhfdG9fY3R4KHByaXYpLCBmLA0KKwkJCQkgICAgIE1U S19KUEVHX0ZNVF9GTEFHX0RFQ19DQVBUVVJFKTsNCiB9DQogDQogc3RhdGljIHZvaWQgbXRrX2pw ZWdfcXVldWVfc3JjX2NoZ19ldmVudChzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgpDQpAQCAtNDIw LDggKzYwMSwzMSBAQCBzdGF0aWMgaW50IG10a19qcGVnX3N1YnNjcmliZV9ldmVudChzdHJ1Y3Qg djRsMl9maCAqZmgsDQogCXJldHVybiB2NGwyX2N0cmxfc3Vic2NyaWJlX2V2ZW50KGZoLCBzdWIp Ow0KIH0NCiANCi1zdGF0aWMgaW50IG10a19qcGVnX2dfc2VsZWN0aW9uKHN0cnVjdCBmaWxlICpm aWxlLCB2b2lkICpwcml2LA0KLQkJCQlzdHJ1Y3QgdjRsMl9zZWxlY3Rpb24gKnMpDQorc3RhdGlj IGludCBtdGtfanBlZ19lbmNfZ19zZWxlY3Rpb24oc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnBy aXYsDQorCQkJCSAgICBzdHJ1Y3QgdjRsMl9zZWxlY3Rpb24gKnMpDQorew0KKwlzdHJ1Y3QgbXRr X2pwZWdfY3R4ICpjdHggPSBtdGtfanBlZ19maF90b19jdHgocHJpdik7DQorDQorCWlmIChzLT50 eXBlICE9IFY0TDJfQlVGX1RZUEVfVklERU9fT1VUUFVUKQ0KKwkJcmV0dXJuIC1FSU5WQUw7DQor DQorCXN3aXRjaCAocy0+dGFyZ2V0KSB7DQorCWNhc2UgVjRMMl9TRUxfVEdUX0NST1A6DQorCWNh c2UgVjRMMl9TRUxfVEdUX0NST1BfQk9VTkRTOg0KKwljYXNlIFY0TDJfU0VMX1RHVF9DUk9QX0RF RkFVTFQ6DQorCQlzLT5yLndpZHRoID0gY3R4LT5vdXRfcS53Ow0KKwkJcy0+ci5oZWlnaHQgPSBj dHgtPm91dF9xLmg7DQorCQlzLT5yLmxlZnQgPSAwOw0KKwkJcy0+ci50b3AgPSAwOw0KKwkJYnJl YWs7DQorCWRlZmF1bHQ6DQorCQlyZXR1cm4gLUVJTlZBTDsNCisJfQ0KKwlyZXR1cm4gMDsNCit9 DQorDQorc3RhdGljIGludCBtdGtfanBlZ19kZWNfZ19zZWxlY3Rpb24oc3RydWN0IGZpbGUgKmZp bGUsIHZvaWQgKnByaXYsDQorCQkJCSAgICBzdHJ1Y3QgdjRsMl9zZWxlY3Rpb24gKnMpDQogew0K IAlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHggPSBtdGtfanBlZ19maF90b19jdHgocHJpdik7DQog DQpAQCAtNDQ2LDExICs2NTAsMzQgQEAgc3RhdGljIGludCBtdGtfanBlZ19nX3NlbGVjdGlvbihz dHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCiAJZGVmYXVsdDoNCiAJCXJldHVybiAtRUlO VkFMOw0KIAl9DQorDQogCXJldHVybiAwOw0KIH0NCiANCi1zdGF0aWMgaW50IG10a19qcGVnX3Nf c2VsZWN0aW9uKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KLQkJCQlzdHJ1Y3QgdjRs Ml9zZWxlY3Rpb24gKnMpDQorc3RhdGljIGludCBtdGtfanBlZ19lbmNfc19zZWxlY3Rpb24oc3Ry dWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQorCQkJCSAgICBzdHJ1Y3QgdjRsMl9zZWxlY3Rp b24gKnMpDQorew0KKwlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHggPSBtdGtfanBlZ19maF90b19j dHgocHJpdik7DQorDQorCWlmIChzLT50eXBlICE9IFY0TDJfQlVGX1RZUEVfVklERU9fT1VUUFVU KQ0KKwkJcmV0dXJuIC1FSU5WQUw7DQorDQorCXN3aXRjaCAocy0+dGFyZ2V0KSB7DQorCWNhc2Ug VjRMMl9TRUxfVEdUX0NST1A6DQorCQlzLT5yLmxlZnQgPSAwOw0KKwkJcy0+ci50b3AgPSAwOw0K KwkJY3R4LT5vdXRfcS53ID0gbWluKHMtPnIud2lkdGgsIGN0eC0+b3V0X3Eudyk7DQorCQljdHgt Pm91dF9xLmggPSBtaW4ocy0+ci5oZWlnaHQsIGN0eC0+b3V0X3EuaCk7DQorCQlicmVhazsNCisJ ZGVmYXVsdDoNCisJCXJldHVybiAtRUlOVkFMOw0KKwl9DQorDQorCXJldHVybiAwOw0KK30NCisN CitzdGF0aWMgaW50IG10a19qcGVnX2RlY19zX3NlbGVjdGlvbihzdHJ1Y3QgZmlsZSAqZmlsZSwg dm9pZCAqcHJpdiwNCisJCQkJICAgIHN0cnVjdCB2NGwyX3NlbGVjdGlvbiAqcykNCiB7DQogCXN0 cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IG10a19qcGVnX2ZoX3RvX2N0eChwcml2KTsNCiANCkBA IC00NjcsNiArNjk0LDcgQEAgc3RhdGljIGludCBtdGtfanBlZ19zX3NlbGVjdGlvbihzdHJ1Y3Qg ZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCiAJZGVmYXVsdDoNCiAJCXJldHVybiAtRUlOVkFMOw0K IAl9DQorDQogCXJldHVybiAwOw0KIH0NCiANCkBAIC00OTUsMjAgKzcyMyw0NyBAQCBzdGF0aWMg aW50IG10a19qcGVnX3FidWYoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsIHN0cnVjdCB2 NGwyX2J1ZmZlciAqYnVmKQ0KIAlyZXR1cm4gdjRsMl9tMm1fcWJ1ZihmaWxlLCBmaC0+bTJtX2N0 eCwgYnVmKTsNCiB9DQogDQotc3RhdGljIGNvbnN0IHN0cnVjdCB2NGwyX2lvY3RsX29wcyBtdGtf anBlZ19pb2N0bF9vcHMgPSB7DQotCS52aWRpb2NfcXVlcnljYXAgICAgICAgICAgICAgICAgPSBt dGtfanBlZ19xdWVyeWNhcCwNCi0JLnZpZGlvY19lbnVtX2ZtdF92aWRfY2FwCT0gbXRrX2pwZWdf ZW51bV9mbXRfdmlkX2NhcCwNCi0JLnZpZGlvY19lbnVtX2ZtdF92aWRfb3V0CT0gbXRrX2pwZWdf ZW51bV9mbXRfdmlkX291dCwNCi0JLnZpZGlvY190cnlfZm10X3ZpZF9jYXBfbXBsYW5lCT0gbXRr X2pwZWdfdHJ5X2ZtdF92aWRfY2FwX21wbGFuZSwNCi0JLnZpZGlvY190cnlfZm10X3ZpZF9vdXRf bXBsYW5lCT0gbXRrX2pwZWdfdHJ5X2ZtdF92aWRfb3V0X21wbGFuZSwNCitzdGF0aWMgY29uc3Qg c3RydWN0IHY0bDJfaW9jdGxfb3BzIG10a19qcGVnX2VuY19pb2N0bF9vcHMgPSB7DQorCS52aWRp b2NfcXVlcnljYXAgICAgICAgICAgICAgICAgPSBtdGtfanBlZ19lbmNfcXVlcnljYXAsDQorCS52 aWRpb2NfZW51bV9mbXRfdmlkX2NhcAk9IG10a19qcGVnX2VuY19lbnVtX2ZtdF92aWRfY2FwLA0K KwkudmlkaW9jX2VudW1fZm10X3ZpZF9vdXQJPSBtdGtfanBlZ19lbmNfZW51bV9mbXRfdmlkX291 dCwNCisJLnZpZGlvY190cnlfZm10X3ZpZF9jYXBfbXBsYW5lCT0gbXRrX2pwZWdfZW5jX3RyeV9m bXRfdmlkX2NhcF9tcGxhbmUsDQorCS52aWRpb2NfdHJ5X2ZtdF92aWRfb3V0X21wbGFuZQk9IG10 a19qcGVnX2VuY190cnlfZm10X3ZpZF9vdXRfbXBsYW5lLA0KKwkudmlkaW9jX2dfZm10X3ZpZF9j YXBfbXBsYW5lICAgID0gbXRrX2pwZWdfZ19mbXRfdmlkX21wbGFuZSwNCisJLnZpZGlvY19nX2Zt dF92aWRfb3V0X21wbGFuZSAgICA9IG10a19qcGVnX2dfZm10X3ZpZF9tcGxhbmUsDQorCS52aWRp b2Nfc19mbXRfdmlkX2NhcF9tcGxhbmUgICAgPSBtdGtfanBlZ19lbmNfc19mbXRfdmlkX2NhcF9t cGxhbmUsDQorCS52aWRpb2Nfc19mbXRfdmlkX291dF9tcGxhbmUgICAgPSBtdGtfanBlZ19lbmNf c19mbXRfdmlkX291dF9tcGxhbmUsDQorCS52aWRpb2NfcWJ1ZiAgICAgICAgICAgICAgICAgICAg PSBtdGtfanBlZ19xYnVmLA0KKwkudmlkaW9jX3N1YnNjcmliZV9ldmVudCAgICAgICAgID0gbXRr X2pwZWdfc3Vic2NyaWJlX2V2ZW50LA0KKwkudmlkaW9jX2dfc2VsZWN0aW9uCQk9IG10a19qcGVn X2VuY19nX3NlbGVjdGlvbiwNCisJLnZpZGlvY19zX3NlbGVjdGlvbgkJPSBtdGtfanBlZ19lbmNf c19zZWxlY3Rpb24sDQorDQorCS52aWRpb2NfY3JlYXRlX2J1ZnMJCT0gdjRsMl9tMm1faW9jdGxf Y3JlYXRlX2J1ZnMsDQorCS52aWRpb2NfcHJlcGFyZV9idWYJCT0gdjRsMl9tMm1faW9jdGxfcHJl cGFyZV9idWYsDQorCS52aWRpb2NfcmVxYnVmcyAgICAgICAgICAgICAgICAgPSB2NGwyX20ybV9p b2N0bF9yZXFidWZzLA0KKwkudmlkaW9jX3F1ZXJ5YnVmICAgICAgICAgICAgICAgID0gdjRsMl9t Mm1faW9jdGxfcXVlcnlidWYsDQorCS52aWRpb2NfZHFidWYgICAgICAgICAgICAgICAgICAgPSB2 NGwyX20ybV9pb2N0bF9kcWJ1ZiwNCisJLnZpZGlvY19leHBidWYgICAgICAgICAgICAgICAgICA9 IHY0bDJfbTJtX2lvY3RsX2V4cGJ1ZiwNCisJLnZpZGlvY19zdHJlYW1vbiAgICAgICAgICAgICAg ICA9IHY0bDJfbTJtX2lvY3RsX3N0cmVhbW9uLA0KKwkudmlkaW9jX3N0cmVhbW9mZiAgICAgICAg ICAgICAgID0gdjRsMl9tMm1faW9jdGxfc3RyZWFtb2ZmLA0KKw0KKwkudmlkaW9jX3Vuc3Vic2Ny aWJlX2V2ZW50CT0gdjRsMl9ldmVudF91bnN1YnNjcmliZSwNCit9Ow0KKw0KK3N0YXRpYyBjb25z dCBzdHJ1Y3QgdjRsMl9pb2N0bF9vcHMgbXRrX2pwZWdfZGVjX2lvY3RsX29wcyA9IHsNCisJLnZp ZGlvY19xdWVyeWNhcCAgICAgICAgICAgICAgICA9IG10a19qcGVnX2RlY19xdWVyeWNhcCwNCisJ LnZpZGlvY19lbnVtX2ZtdF92aWRfY2FwCT0gbXRrX2pwZWdfZGVjX2VudW1fZm10X3ZpZF9jYXAs DQorCS52aWRpb2NfZW51bV9mbXRfdmlkX291dAk9IG10a19qcGVnX2RlY19lbnVtX2ZtdF92aWRf b3V0LA0KKwkudmlkaW9jX3RyeV9mbXRfdmlkX2NhcF9tcGxhbmUJPSBtdGtfanBlZ19kZWNfdHJ5 X2ZtdF92aWRfY2FwX21wbGFuZSwNCisJLnZpZGlvY190cnlfZm10X3ZpZF9vdXRfbXBsYW5lCT0g bXRrX2pwZWdfZGVjX3RyeV9mbXRfdmlkX291dF9tcGxhbmUsDQogCS52aWRpb2NfZ19mbXRfdmlk X2NhcF9tcGxhbmUgICAgPSBtdGtfanBlZ19nX2ZtdF92aWRfbXBsYW5lLA0KIAkudmlkaW9jX2df Zm10X3ZpZF9vdXRfbXBsYW5lICAgID0gbXRrX2pwZWdfZ19mbXRfdmlkX21wbGFuZSwNCi0JLnZp ZGlvY19zX2ZtdF92aWRfY2FwX21wbGFuZSAgICA9IG10a19qcGVnX3NfZm10X3ZpZF9jYXBfbXBs YW5lLA0KLQkudmlkaW9jX3NfZm10X3ZpZF9vdXRfbXBsYW5lICAgID0gbXRrX2pwZWdfc19mbXRf dmlkX291dF9tcGxhbmUsDQorCS52aWRpb2Nfc19mbXRfdmlkX2NhcF9tcGxhbmUgICAgPSBtdGtf anBlZ19kZWNfc19mbXRfdmlkX2NhcF9tcGxhbmUsDQorCS52aWRpb2Nfc19mbXRfdmlkX291dF9t cGxhbmUgICAgPSBtdGtfanBlZ19kZWNfc19mbXRfdmlkX291dF9tcGxhbmUsDQogCS52aWRpb2Nf cWJ1ZiAgICAgICAgICAgICAgICAgICAgPSBtdGtfanBlZ19xYnVmLA0KIAkudmlkaW9jX3N1YnNj cmliZV9ldmVudCAgICAgICAgID0gbXRrX2pwZWdfc3Vic2NyaWJlX2V2ZW50LA0KLQkudmlkaW9j X2dfc2VsZWN0aW9uCQk9IG10a19qcGVnX2dfc2VsZWN0aW9uLA0KLQkudmlkaW9jX3Nfc2VsZWN0 aW9uCQk9IG10a19qcGVnX3Nfc2VsZWN0aW9uLA0KKwkudmlkaW9jX2dfc2VsZWN0aW9uCQk9IG10 a19qcGVnX2RlY19nX3NlbGVjdGlvbiwNCisJLnZpZGlvY19zX3NlbGVjdGlvbgkJPSBtdGtfanBl Z19kZWNfc19zZWxlY3Rpb24sDQogDQogCS52aWRpb2NfY3JlYXRlX2J1ZnMJCT0gdjRsMl9tMm1f aW9jdGxfY3JlYXRlX2J1ZnMsDQogCS52aWRpb2NfcHJlcGFyZV9idWYJCT0gdjRsMl9tMm1faW9j dGxfcHJlcGFyZV9idWYsDQpAQCAtNTg2LDggKzg0MSw5IEBAIHN0YXRpYyBib29sIG10a19qcGVn X2NoZWNrX3Jlc29sdXRpb25fY2hhbmdlKHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCwNCiAJfQ0K IA0KIAlxX2RhdGEgPSAmY3R4LT5jYXBfcTsNCi0JaWYgKHFfZGF0YS0+Zm10ICE9IG10a19qcGVn X2ZpbmRfZm9ybWF0KGN0eCwgcGFyYW0tPmRzdF9mb3VyY2MsDQotCQkJCQkJTVRLX0pQRUdfRk1U X1RZUEVfQ0FQVFVSRSkpIHsNCisJaWYgKHFfZGF0YS0+Zm10ICE9DQorCSAgICBtdGtfanBlZ19m aW5kX2Zvcm1hdChwYXJhbS0+ZHN0X2ZvdXJjYywNCisJCQkJIE1US19KUEVHX0ZNVF9GTEFHX0RF Q19DQVBUVVJFKSkgew0KIAkJdjRsMl9kYmcoMSwgZGVidWcsICZqcGVnLT52NGwyX2RldiwgImZv cm1hdCBjaGFuZ2VcbiIpOw0KIAkJcmV0dXJuIHRydWU7DQogCX0NCkBAIC02MDgsOSArODY0LDgg QEAgc3RhdGljIHZvaWQgbXRrX2pwZWdfc2V0X3F1ZXVlX2RhdGEoc3RydWN0IG10a19qcGVnX2N0 eCAqY3R4LA0KIAlxX2RhdGEgPSAmY3R4LT5jYXBfcTsNCiAJcV9kYXRhLT53ID0gcGFyYW0tPmRl Y193Ow0KIAlxX2RhdGEtPmggPSBwYXJhbS0+ZGVjX2g7DQotCXFfZGF0YS0+Zm10ID0gbXRrX2pw ZWdfZmluZF9mb3JtYXQoY3R4LA0KLQkJCQkJICAgcGFyYW0tPmRzdF9mb3VyY2MsDQotCQkJCQkg ICBNVEtfSlBFR19GTVRfVFlQRV9DQVBUVVJFKTsNCisJcV9kYXRhLT5mbXQgPSBtdGtfanBlZ19m aW5kX2Zvcm1hdChwYXJhbS0+ZHN0X2ZvdXJjYywNCisJCQkJCSAgIE1US19KUEVHX0ZNVF9GTEFH X0RFQ19DQVBUVVJFKTsNCiANCiAJZm9yIChpID0gMDsgaSA8IHFfZGF0YS0+Zm10LT5jb2xwbGFu ZXM7IGkrKykgew0KIAkJcV9kYXRhLT5ieXRlc3BlcmxpbmVbaV0gPSBwYXJhbS0+bWVtX3N0cmlk ZVtpXTsNCkBAIC02MjcsNyArODgyLDE4IEBAIHN0YXRpYyB2b2lkIG10a19qcGVnX3NldF9xdWV1 ZV9kYXRhKHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCwNCiAJCSBwYXJhbS0+ZGVjX3csIHBhcmFt LT5kZWNfaCk7DQogfQ0KIA0KLXN0YXRpYyB2b2lkIG10a19qcGVnX2J1Zl9xdWV1ZShzdHJ1Y3Qg dmIyX2J1ZmZlciAqdmIpDQorc3RhdGljIHZvaWQgbXRrX2pwZWdfZW5jX2J1Zl9xdWV1ZShzdHJ1 Y3QgdmIyX2J1ZmZlciAqdmIpDQorew0KKwlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHggPSB2YjJf Z2V0X2Rydl9wcml2KHZiLT52YjJfcXVldWUpOw0KKwlzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpqcGVn ID0gY3R4LT5qcGVnOw0KKw0KKwl2NGwyX2RiZygyLCBkZWJ1ZywgJmpwZWctPnY0bDJfZGV2LCAi KCVkKSBidWZfcSBpZD0lZCwgdmI9JXBcbiIsDQorCQkgdmItPnZiMl9xdWV1ZS0+dHlwZSwgdmIt PmluZGV4LCB2Yik7DQorDQorCXY0bDJfbTJtX2J1Zl9xdWV1ZShjdHgtPmZoLm0ybV9jdHgsIHRv X3ZiMl92NGwyX2J1ZmZlcih2YikpOw0KK30NCisNCitzdGF0aWMgdm9pZCBtdGtfanBlZ19kZWNf YnVmX3F1ZXVlKHN0cnVjdCB2YjJfYnVmZmVyICp2YikNCiB7DQogCXN0cnVjdCBtdGtfanBlZ19j dHggKmN0eCA9IHZiMl9nZXRfZHJ2X3ByaXYodmItPnZiMl9xdWV1ZSk7DQogCXN0cnVjdCBtdGtf anBlZ19kZWNfcGFyYW0gKnBhcmFtOw0KQEAgLTY3OSw3ICs5NDUsMTYgQEAgc3RhdGljIHN0cnVj dCB2YjJfdjRsMl9idWZmZXIgKm10a19qcGVnX2J1Zl9yZW1vdmUoc3RydWN0IG10a19qcGVnX2N0 eCAqY3R4LA0KIAkJcmV0dXJuIHY0bDJfbTJtX2RzdF9idWZfcmVtb3ZlKGN0eC0+ZmgubTJtX2N0 eCk7DQogfQ0KIA0KLXN0YXRpYyB2b2lkIG10a19qcGVnX3N0b3Bfc3RyZWFtaW5nKHN0cnVjdCB2 YjJfcXVldWUgKnEpDQorc3RhdGljIHZvaWQgbXRrX2pwZWdfZW5jX3N0b3Bfc3RyZWFtaW5nKHN0 cnVjdCB2YjJfcXVldWUgKnEpDQorew0KKwlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHggPSB2YjJf Z2V0X2Rydl9wcml2KHEpOw0KKwlzdHJ1Y3QgdmIyX3Y0bDJfYnVmZmVyICp2YjsNCisNCisJd2hp bGUgKCh2YiA9IG10a19qcGVnX2J1Zl9yZW1vdmUoY3R4LCBxLT50eXBlKSkpDQorCQl2NGwyX20y bV9idWZfZG9uZSh2YiwgVkIyX0JVRl9TVEFURV9FUlJPUik7DQorfQ0KKw0KK3N0YXRpYyB2b2lk IG10a19qcGVnX2RlY19zdG9wX3N0cmVhbWluZyhzdHJ1Y3QgdmIyX3F1ZXVlICpxKQ0KIHsNCiAJ c3RydWN0IG10a19qcGVnX2N0eCAqY3R4ID0gdmIyX2dldF9kcnZfcHJpdihxKTsNCiAJc3RydWN0 IHZiMl92NGwyX2J1ZmZlciAqdmI7DQpAQCAtNzA1LDEzICs5ODAsMjIgQEAgc3RhdGljIHZvaWQg bXRrX2pwZWdfc3RvcF9zdHJlYW1pbmcoc3RydWN0IHZiMl9xdWV1ZSAqcSkNCiAJCXY0bDJfbTJt X2J1Zl9kb25lKHZiLCBWQjJfQlVGX1NUQVRFX0VSUk9SKTsNCiB9DQogDQotc3RhdGljIGNvbnN0 IHN0cnVjdCB2YjJfb3BzIG10a19qcGVnX3FvcHMgPSB7DQorc3RhdGljIGNvbnN0IHN0cnVjdCB2 YjJfb3BzIG10a19qcGVnX2RlY19xb3BzID0gew0KIAkucXVldWVfc2V0dXAgICAgICAgID0gbXRr X2pwZWdfcXVldWVfc2V0dXAsDQogCS5idWZfcHJlcGFyZSAgICAgICAgPSBtdGtfanBlZ19idWZf cHJlcGFyZSwNCi0JLmJ1Zl9xdWV1ZSAgICAgICAgICA9IG10a19qcGVnX2J1Zl9xdWV1ZSwNCisJ LmJ1Zl9xdWV1ZSAgICAgICAgICA9IG10a19qcGVnX2RlY19idWZfcXVldWUsDQogCS53YWl0X3By ZXBhcmUgICAgICAgPSB2YjJfb3BzX3dhaXRfcHJlcGFyZSwNCiAJLndhaXRfZmluaXNoICAgICAg ICA9IHZiMl9vcHNfd2FpdF9maW5pc2gsDQotCS5zdG9wX3N0cmVhbWluZyAgICAgPSBtdGtfanBl Z19zdG9wX3N0cmVhbWluZywNCisJLnN0b3Bfc3RyZWFtaW5nICAgICA9IG10a19qcGVnX2RlY19z dG9wX3N0cmVhbWluZywNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdmIyX29wcyBtdGtf anBlZ19lbmNfcW9wcyA9IHsNCisJLnF1ZXVlX3NldHVwICAgICAgICA9IG10a19qcGVnX3F1ZXVl X3NldHVwLA0KKwkuYnVmX3ByZXBhcmUgICAgICAgID0gbXRrX2pwZWdfYnVmX3ByZXBhcmUsDQor CS5idWZfcXVldWUgICAgICAgICAgPSBtdGtfanBlZ19lbmNfYnVmX3F1ZXVlLA0KKwkud2FpdF9w cmVwYXJlICAgICAgID0gdmIyX29wc193YWl0X3ByZXBhcmUsDQorCS53YWl0X2ZpbmlzaCAgICAg ICAgPSB2YjJfb3BzX3dhaXRfZmluaXNoLA0KKwkuc3RvcF9zdHJlYW1pbmcgICAgID0gbXRrX2pw ZWdfZW5jX3N0b3Bfc3RyZWFtaW5nLA0KIH07DQogDQogc3RhdGljIHZvaWQgbXRrX2pwZWdfc2V0 X2RlY19zcmMoc3RydWN0IG10a19qcGVnX2N0eCAqY3R4LA0KQEAgLTc1MSw3ICsxMDM1LDg2IEBA IHN0YXRpYyBpbnQgbXRrX2pwZWdfc2V0X2RlY19kc3Qoc3RydWN0IG10a19qcGVnX2N0eCAqY3R4 LA0KIAlyZXR1cm4gMDsNCiB9DQogDQotc3RhdGljIHZvaWQgbXRrX2pwZWdfZGV2aWNlX3J1bih2 b2lkICpwcml2KQ0KK3N0YXRpYyB2b2lkIG10a19qcGVnX3NldF9lbmNfZHN0KHN0cnVjdCBtdGtf anBlZ19jdHggKmN0eCwgdm9pZCBfX2lvbWVtICpiYXNlLA0KKwkJCQkgc3RydWN0IHZiMl9idWZm ZXIgKmRzdF9idWYsDQorCQkJCSBzdHJ1Y3QgbXRrX2pwZWdfZW5jX2JzICpicykNCit7DQorCWJz LT5kbWFfYWRkciA9IHZiMl9kbWFfY29udGlnX3BsYW5lX2RtYV9hZGRyKGRzdF9idWYsIDApOw0K Kwlicy0+ZG1hX2FkZHJfb2Zmc2V0ID0gY3R4LT5lbmFibGVfZXhpZiA/IE1US19KUEVHX0RFRkFV TFRfRVhJRl9TSVpFIDogMDsNCisJYnMtPmRtYV9hZGRyX29mZnNldG1hc2sgPSBicy0+ZG1hX2Fk ZHIgJiBKUEVHX0VOQ19EU1RfQUREUl9PRkZTRVRfTUFTSzsNCisJYnMtPnNpemUgPSB2YjJfcGxh bmVfc2l6ZShkc3RfYnVmLCAwKTsNCisNCisJbXRrX2pwZWdfZW5jX3NldF9kc3RfYWRkcihiYXNl LCBicy0+ZG1hX2FkZHIsIGJzLT5zaXplLA0KKwkJCQkgIGJzLT5kbWFfYWRkcl9vZmZzZXQsDQor CQkJCSAgYnMtPmRtYV9hZGRyX29mZnNldG1hc2spOw0KK30NCisNCitzdGF0aWMgdm9pZCBtdGtf anBlZ19zZXRfZW5jX3NyYyhzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsIHZvaWQgX19pb21lbSAq YmFzZSwNCisJCQkJIHN0cnVjdCB2YjJfYnVmZmVyICpzcmNfYnVmKQ0KK3sNCisJaW50IGk7DQor CWRtYV9hZGRyX3QJZG1hX2FkZHI7DQorDQorCW10a19qcGVnX2VuY19zZXRfaW1nX3NpemUoYmFz ZSwgY3R4LT5vdXRfcS53LCBjdHgtPm91dF9xLmgpOw0KKwltdGtfanBlZ19lbmNfc2V0X2Jsa19u dW0oYmFzZSwgY3R4LT5vdXRfcS5mbXQtPmZvdXJjYywgY3R4LT5vdXRfcS53LA0KKwkJCQkgY3R4 LT5vdXRfcS5oKTsNCisJbXRrX2pwZWdfZW5jX3NldF9zdHJpZGUoYmFzZSwgY3R4LT5vdXRfcS5m bXQtPmZvdXJjYywgY3R4LT5vdXRfcS53LA0KKwkJCQljdHgtPm91dF9xLmgsIGN0eC0+b3V0X3Eu Ynl0ZXNwZXJsaW5lWzBdKTsNCisNCisJZm9yIChpID0gMDsgaSA8IHNyY19idWYtPm51bV9wbGFu ZXM7IGkrKykgew0KKwkJZG1hX2FkZHIgPSB2YjJfZG1hX2NvbnRpZ19wbGFuZV9kbWFfYWRkcihz cmNfYnVmLCBpKSArDQorCQkJICAgc3JjX2J1Zi0+cGxhbmVzW2ldLmRhdGFfb2Zmc2V0Ow0KKwkJ bXRrX2pwZWdfZW5jX3NldF9zcmNfYWRkcihiYXNlLCBkbWFfYWRkciwgaSk7DQorCX0NCit9DQor DQorc3RhdGljIHZvaWQgbXRrX2pwZWdfZW5jX2RldmljZV9ydW4odm9pZCAqcHJpdikNCit7DQor CXN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IHByaXY7DQorCXN0cnVjdCBtdGtfanBlZ19kZXYg KmpwZWcgPSBjdHgtPmpwZWc7DQorCXN0cnVjdCB2YjJfdjRsMl9idWZmZXIgKnNyY19idWYsICpk c3RfYnVmOw0KKwllbnVtIHZiMl9idWZmZXJfc3RhdGUgYnVmX3N0YXRlID0gVkIyX0JVRl9TVEFU RV9FUlJPUjsNCisJdW5zaWduZWQgbG9uZyBmbGFnczsNCisJc3RydWN0IG10a19qcGVnX3NyY19i dWYgKmpwZWdfc3JjX2J1ZjsNCisJc3RydWN0IG10a19qcGVnX2VuY19icyBlbmNfYnM7DQorCWlu dCBpLCByZXQ7DQorDQorCXNyY19idWYgPSB2NGwyX20ybV9uZXh0X3NyY19idWYoY3R4LT5maC5t Mm1fY3R4KTsNCisJZHN0X2J1ZiA9IHY0bDJfbTJtX25leHRfZHN0X2J1ZihjdHgtPmZoLm0ybV9j dHgpOw0KKwlqcGVnX3NyY19idWYgPSBtdGtfanBlZ192YjJfdG9fc3JjYnVmKCZzcmNfYnVmLT52 YjJfYnVmKTsNCisNCisJaWYgKGpwZWdfc3JjX2J1Zi0+ZmxhZ3MgJiBNVEtfSlBFR19CVUZfRkxB R1NfTEFTVF9GUkFNRSkgew0KKwkJZm9yIChpID0gMDsgaSA8IGRzdF9idWYtPnZiMl9idWYubnVt X3BsYW5lczsgaSsrKQ0KKwkJCXZiMl9zZXRfcGxhbmVfcGF5bG9hZCgmZHN0X2J1Zi0+dmIyX2J1 ZiwgaSwgMCk7DQorCQlidWZfc3RhdGUgPSBWQjJfQlVGX1NUQVRFX0RPTkU7DQorCQlnb3RvIGVu Y19lbmQ7DQorCX0NCisNCisJcmV0ID0gcG1fcnVudGltZV9nZXRfc3luYyhqcGVnLT5kZXYpOw0K KwlpZiAocmV0IDwgMCkNCisJCWdvdG8gZW5jX2VuZDsNCisNCisJc3Bpbl9sb2NrX2lycXNhdmUo JmpwZWctPmh3X2xvY2ssIGZsYWdzKTsNCisJbXRrX2pwZWdfZW5jX3Jlc2V0KGpwZWctPnJlZ19i YXNlKTsNCisNCisJbXRrX2pwZWdfc2V0X2VuY19kc3QoY3R4LCBqcGVnLT5yZWdfYmFzZSwgJmRz dF9idWYtPnZiMl9idWYsICZlbmNfYnMpOw0KKwltdGtfanBlZ19zZXRfZW5jX3NyYyhjdHgsIGpw ZWctPnJlZ19iYXNlLCAmc3JjX2J1Zi0+dmIyX2J1Zik7DQorCW10a19qcGVnX2VuY19zZXRfY29u ZmlnKGpwZWctPnJlZ19iYXNlLCBjdHgtPm91dF9xLmZtdC0+aHdfZm9ybWF0LA0KKwkJCQljdHgt PmVuYWJsZV9leGlmLCBjdHgtPmVuY19xdWFsaXR5LA0KKwkJCQljdHgtPnJlc3RhcnRfaW50ZXJ2 YWwpOw0KKwltdGtfanBlZ19lbmNfc3RhcnQoanBlZy0+cmVnX2Jhc2UpOw0KKwlzcGluX3VubG9j a19pcnFyZXN0b3JlKCZqcGVnLT5od19sb2NrLCBmbGFncyk7DQorCXJldHVybjsNCisNCitlbmNf ZW5kOg0KKwl2NGwyX20ybV9zcmNfYnVmX3JlbW92ZShjdHgtPmZoLm0ybV9jdHgpOw0KKwl2NGwy X20ybV9kc3RfYnVmX3JlbW92ZShjdHgtPmZoLm0ybV9jdHgpOw0KKwl2NGwyX20ybV9idWZfZG9u ZShzcmNfYnVmLCBidWZfc3RhdGUpOw0KKwl2NGwyX20ybV9idWZfZG9uZShkc3RfYnVmLCBidWZf c3RhdGUpOw0KKwl2NGwyX20ybV9qb2JfZmluaXNoKGpwZWctPm0ybV9kZXYsIGN0eC0+ZmgubTJt X2N0eCk7DQorfQ0KKw0KK3N0YXRpYyB2b2lkIG10a19qcGVnX2RlY19kZXZpY2VfcnVuKHZvaWQg KnByaXYpDQogew0KIAlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHggPSBwcml2Ow0KIAlzdHJ1Y3Qg bXRrX2pwZWdfZGV2ICpqcGVnID0gY3R4LT5qcGVnOw0KQEAgLTc4NiwxNSArMTE0OSwxNiBAQCBz dGF0aWMgdm9pZCBtdGtfanBlZ19kZXZpY2VfcnVuKHZvaWQgKnByaXYpDQogCQlnb3RvIGRlY19l bmQ7DQogDQogCW10a19qcGVnX3NldF9kZWNfc3JjKGN0eCwgJnNyY19idWYtPnZiMl9idWYsICZi cyk7DQotCWlmIChtdGtfanBlZ19zZXRfZGVjX2RzdChjdHgsICZqcGVnX3NyY19idWYtPmRlY19w YXJhbSwgJmRzdF9idWYtPnZiMl9idWYsICZmYikpDQorCWlmIChtdGtfanBlZ19zZXRfZGVjX2Rz dChjdHgsICZqcGVnX3NyY19idWYtPmRlY19wYXJhbSwNCisJCQkJICZkc3RfYnVmLT52YjJfYnVm LCAmZmIpKQ0KIAkJZ290byBkZWNfZW5kOw0KIA0KIAlzcGluX2xvY2tfaXJxc2F2ZSgmanBlZy0+ aHdfbG9jaywgZmxhZ3MpOw0KLQltdGtfanBlZ19kZWNfcmVzZXQoanBlZy0+ZGVjX3JlZ19iYXNl KTsNCi0JbXRrX2pwZWdfZGVjX3NldF9jb25maWcoanBlZy0+ZGVjX3JlZ19iYXNlLA0KKwltdGtf anBlZ19kZWNfcmVzZXQoanBlZy0+cmVnX2Jhc2UpOw0KKwltdGtfanBlZ19kZWNfc2V0X2NvbmZp ZyhqcGVnLT5yZWdfYmFzZSwNCiAJCQkJJmpwZWdfc3JjX2J1Zi0+ZGVjX3BhcmFtLCAmYnMsICZm Yik7DQogDQotCW10a19qcGVnX2RlY19zdGFydChqcGVnLT5kZWNfcmVnX2Jhc2UpOw0KKwltdGtf anBlZ19kZWNfc3RhcnQoanBlZy0+cmVnX2Jhc2UpOw0KIAlzcGluX3VubG9ja19pcnFyZXN0b3Jl KCZqcGVnLT5od19sb2NrLCBmbGFncyk7DQogCXJldHVybjsNCiANCkBAIC04MDYsMjAgKzExNzAs MzAgQEAgc3RhdGljIHZvaWQgbXRrX2pwZWdfZGV2aWNlX3J1bih2b2lkICpwcml2KQ0KIAl2NGwy X20ybV9qb2JfZmluaXNoKGpwZWctPm0ybV9kZXYsIGN0eC0+ZmgubTJtX2N0eCk7DQogfQ0KIA0K LXN0YXRpYyBpbnQgbXRrX2pwZWdfam9iX3JlYWR5KHZvaWQgKnByaXYpDQorc3RhdGljIGludCBt dGtfanBlZ19lbmNfam9iX3JlYWR5KHZvaWQgKnByaXYpDQorew0KKwkJcmV0dXJuIDE7DQorfQ0K Kw0KK3N0YXRpYyBpbnQgbXRrX2pwZWdfZGVjX2pvYl9yZWFkeSh2b2lkICpwcml2KQ0KIHsNCiAJ c3RydWN0IG10a19qcGVnX2N0eCAqY3R4ID0gcHJpdjsNCiANCiAJcmV0dXJuIChjdHgtPnN0YXRl ID09IE1US19KUEVHX1JVTk5JTkcpID8gMSA6IDA7DQogfQ0KIA0KLXN0YXRpYyBjb25zdCBzdHJ1 Y3QgdjRsMl9tMm1fb3BzIG10a19qcGVnX20ybV9vcHMgPSB7DQotCS5kZXZpY2VfcnVuID0gbXRr X2pwZWdfZGV2aWNlX3J1biwNCi0JLmpvYl9yZWFkeSAgPSBtdGtfanBlZ19qb2JfcmVhZHksDQor c3RhdGljIGNvbnN0IHN0cnVjdCB2NGwyX20ybV9vcHMgbXRrX2pwZWdfZW5jX20ybV9vcHMgPSB7 DQorCS5kZXZpY2VfcnVuID0gbXRrX2pwZWdfZW5jX2RldmljZV9ydW4sDQorCS5qb2JfcmVhZHkg ID0gbXRrX2pwZWdfZW5jX2pvYl9yZWFkeSwNCiB9Ow0KIA0KLXN0YXRpYyBpbnQgbXRrX2pwZWdf cXVldWVfaW5pdCh2b2lkICpwcml2LCBzdHJ1Y3QgdmIyX3F1ZXVlICpzcmNfdnEsDQotCQkJICAg ICAgIHN0cnVjdCB2YjJfcXVldWUgKmRzdF92cSkNCitzdGF0aWMgY29uc3Qgc3RydWN0IHY0bDJf bTJtX29wcyBtdGtfanBlZ19kZWNfbTJtX29wcyA9IHsNCisJLmRldmljZV9ydW4gPSBtdGtfanBl Z19kZWNfZGV2aWNlX3J1biwNCisJLmpvYl9yZWFkeSAgPSBtdGtfanBlZ19kZWNfam9iX3JlYWR5 LA0KK307DQorDQorc3RhdGljIGludCBtdGtfanBlZ19kZWNfcXVldWVfaW5pdCh2b2lkICpwcml2 LCBzdHJ1Y3QgdmIyX3F1ZXVlICpzcmNfdnEsDQorCQkJCSAgIHN0cnVjdCB2YjJfcXVldWUgKmRz dF92cSkNCiB7DQogCXN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IHByaXY7DQogCWludCByZXQ7 DQpAQCAtODI4LDcgKzEyMDIsNyBAQCBzdGF0aWMgaW50IG10a19qcGVnX3F1ZXVlX2luaXQodm9p ZCAqcHJpdiwgc3RydWN0IHZiMl9xdWV1ZSAqc3JjX3ZxLA0KIAlzcmNfdnEtPmlvX21vZGVzID0g VkIyX0RNQUJVRiB8IFZCMl9NTUFQOw0KIAlzcmNfdnEtPmRydl9wcml2ID0gY3R4Ow0KIAlzcmNf dnEtPmJ1Zl9zdHJ1Y3Rfc2l6ZSA9IHNpemVvZihzdHJ1Y3QgbXRrX2pwZWdfc3JjX2J1Zik7DQot CXNyY192cS0+b3BzID0gJm10a19qcGVnX3FvcHM7DQorCXNyY192cS0+b3BzID0gJm10a19qcGVn X2RlY19xb3BzOw0KIAlzcmNfdnEtPm1lbV9vcHMgPSAmdmIyX2RtYV9jb250aWdfbWVtb3BzOw0K IAlzcmNfdnEtPnRpbWVzdGFtcF9mbGFncyA9IFY0TDJfQlVGX0ZMQUdfVElNRVNUQU1QX0NPUFk7 DQogCXNyY192cS0+bG9jayA9ICZjdHgtPmpwZWctPmxvY2s7DQpAQCAtODQxLDcgKzEyMTUsNyBA QCBzdGF0aWMgaW50IG10a19qcGVnX3F1ZXVlX2luaXQodm9pZCAqcHJpdiwgc3RydWN0IHZiMl9x dWV1ZSAqc3JjX3ZxLA0KIAlkc3RfdnEtPmlvX21vZGVzID0gVkIyX0RNQUJVRiB8IFZCMl9NTUFQ Ow0KIAlkc3RfdnEtPmRydl9wcml2ID0gY3R4Ow0KIAlkc3RfdnEtPmJ1Zl9zdHJ1Y3Rfc2l6ZSA9 IHNpemVvZihzdHJ1Y3QgdjRsMl9tMm1fYnVmZmVyKTsNCi0JZHN0X3ZxLT5vcHMgPSAmbXRrX2pw ZWdfcW9wczsNCisJZHN0X3ZxLT5vcHMgPSAmbXRrX2pwZWdfZGVjX3FvcHM7DQogCWRzdF92cS0+ bWVtX29wcyA9ICZ2YjJfZG1hX2NvbnRpZ19tZW1vcHM7DQogCWRzdF92cS0+dGltZXN0YW1wX2Zs YWdzID0gVjRMMl9CVUZfRkxBR19USU1FU1RBTVBfQ09QWTsNCiAJZHN0X3ZxLT5sb2NrID0gJmN0 eC0+anBlZy0+bG9jazsNCkBAIC04NTEsMjQgKzEyMjUsMTEyIEBAIHN0YXRpYyBpbnQgbXRrX2pw ZWdfcXVldWVfaW5pdCh2b2lkICpwcml2LCBzdHJ1Y3QgdmIyX3F1ZXVlICpzcmNfdnEsDQogCXJl dHVybiByZXQ7DQogfQ0KIA0KLXN0YXRpYyB2b2lkIG10a19qcGVnX2Nsa19vbihzdHJ1Y3QgbXRr X2pwZWdfZGV2ICpqcGVnKQ0KK3N0YXRpYyBpbnQgbXRrX2pwZWdfZW5jX3F1ZXVlX2luaXQodm9p ZCAqcHJpdiwgc3RydWN0IHZiMl9xdWV1ZSAqc3JjX3ZxLA0KKwkJCQkgICBzdHJ1Y3QgdmIyX3F1 ZXVlICpkc3RfdnEpDQogew0KKwlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHggPSBwcml2Ow0KIAlp bnQgcmV0Ow0KIA0KKwlzcmNfdnEtPnR5cGUgPSBWNEwyX0JVRl9UWVBFX1ZJREVPX09VVFBVVF9N UExBTkU7DQorCXNyY192cS0+aW9fbW9kZXMgPSBWQjJfRE1BQlVGIHwgVkIyX01NQVA7DQorCXNy Y192cS0+ZHJ2X3ByaXYgPSBjdHg7DQorCXNyY192cS0+YnVmX3N0cnVjdF9zaXplID0gc2l6ZW9m KHN0cnVjdCBtdGtfanBlZ19zcmNfYnVmKTsNCisJc3JjX3ZxLT5vcHMgPSAmbXRrX2pwZWdfZW5j X3FvcHM7DQorCXNyY192cS0+bWVtX29wcyA9ICZ2YjJfZG1hX2NvbnRpZ19tZW1vcHM7DQorCXNy Y192cS0+dGltZXN0YW1wX2ZsYWdzID0gVjRMMl9CVUZfRkxBR19USU1FU1RBTVBfQ09QWTsNCisJ c3JjX3ZxLT5sb2NrID0gJmN0eC0+anBlZy0+bG9jazsNCisJc3JjX3ZxLT5kZXYgPSBjdHgtPmpw ZWctPmRldjsNCisJcmV0ID0gdmIyX3F1ZXVlX2luaXQoc3JjX3ZxKTsNCisJaWYgKHJldCkNCisJ CXJldHVybiByZXQ7DQorDQorCWRzdF92cS0+dHlwZSA9IFY0TDJfQlVGX1RZUEVfVklERU9fQ0FQ VFVSRV9NUExBTkU7DQorCWRzdF92cS0+aW9fbW9kZXMgPSBWQjJfRE1BQlVGIHwgVkIyX01NQVA7 DQorCWRzdF92cS0+ZHJ2X3ByaXYgPSBjdHg7DQorCWRzdF92cS0+YnVmX3N0cnVjdF9zaXplID0g c2l6ZW9mKHN0cnVjdCB2NGwyX20ybV9idWZmZXIpOw0KKwlkc3RfdnEtPm9wcyA9ICZtdGtfanBl Z19lbmNfcW9wczsNCisJZHN0X3ZxLT5tZW1fb3BzID0gJnZiMl9kbWFfY29udGlnX21lbW9wczsN CisJZHN0X3ZxLT50aW1lc3RhbXBfZmxhZ3MgPSBWNEwyX0JVRl9GTEFHX1RJTUVTVEFNUF9DT1BZ Ow0KKwlkc3RfdnEtPmxvY2sgPSAmY3R4LT5qcGVnLT5sb2NrOw0KKwlkc3RfdnEtPmRldiA9IGN0 eC0+anBlZy0+ZGV2Ow0KKwlyZXQgPSB2YjJfcXVldWVfaW5pdChkc3RfdnEpOw0KKw0KKwlyZXR1 cm4gcmV0Ow0KK30NCisNCitzdGF0aWMgdm9pZCBtdGtfanBlZ19jbGtfb24oc3RydWN0IG10a19q cGVnX2RldiAqanBlZykNCit7DQorCWludCByZXQsIGk7DQorDQogCXJldCA9IG10a19zbWlfbGFy Yl9nZXQoanBlZy0+bGFyYik7DQogCWlmIChyZXQpDQogCQlkZXZfZXJyKGpwZWctPmRldiwgIm10 a19zbWlfbGFyYl9nZXQgbGFyYnZkZWMgZmFpbCAlZFxuIiwgcmV0KTsNCi0JY2xrX3ByZXBhcmVf ZW5hYmxlKGpwZWctPmNsa19qZGVjX3NtaSk7DQotCWNsa19wcmVwYXJlX2VuYWJsZShqcGVnLT5j bGtfamRlYyk7DQorDQorCWZvciAoaSA9IDA7IGkgPCBqcGVnLT52YXJpYW50LT5udW1fY2xvY2tz OyBpKyspIHsNCisJCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShqcGVnLT5jbG9ja3NbaV0pOw0K KwkJaWYgKHJldCkgew0KKwkJCXdoaWxlICgtLWkgPj0gMCkNCisJCQkJY2xrX2Rpc2FibGVfdW5w cmVwYXJlKGpwZWctPmNsb2Nrc1tpXSk7DQorCQl9DQorCX0NCiB9DQogDQogc3RhdGljIHZvaWQg bXRrX2pwZWdfY2xrX29mZihzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpqcGVnKQ0KIHsNCi0JY2xrX2Rp c2FibGVfdW5wcmVwYXJlKGpwZWctPmNsa19qZGVjKTsNCi0JY2xrX2Rpc2FibGVfdW5wcmVwYXJl KGpwZWctPmNsa19qZGVjX3NtaSk7DQorCWludCBpOw0KKw0KKwlmb3IgKGkgPSBqcGVnLT52YXJp YW50LT5udW1fY2xvY2tzIC0gMTsgaSA+PSAwOyBpLS0pDQorCQljbGtfZGlzYWJsZV91bnByZXBh cmUoanBlZy0+Y2xvY2tzW2ldKTsNCiAJbXRrX3NtaV9sYXJiX3B1dChqcGVnLT5sYXJiKTsNCiB9 DQogDQorc3RhdGljIGlycXJldHVybl90IG10a19qcGVnX2VuY19pcnEoaW50IGlycSwgdm9pZCAq cHJpdikNCit7DQorCXN0cnVjdCBtdGtfanBlZ19kZXYgKmpwZWcgPSBwcml2Ow0KKwlzdHJ1Y3Qg bXRrX2pwZWdfY3R4ICpjdHg7DQorCXN0cnVjdCB2YjJfdjRsMl9idWZmZXIgKnNyY19idWYsICpk c3RfYnVmOw0KKwlzdHJ1Y3QgbXRrX2pwZWdfc3JjX2J1ZiAqanBlZ19zcmNfYnVmOw0KKwllbnVt IHZiMl9idWZmZXJfc3RhdGUgYnVmX3N0YXRlID0gVkIyX0JVRl9TVEFURV9FUlJPUjsNCisJdTMy IGVuY19pcnFfcmV0Ow0KKwl1MzIgZW5jX3JldCwgcmVzdWx0X3NpemU7DQorDQorCXNwaW5fbG9j aygmanBlZy0+aHdfbG9jayk7DQorDQorCWN0eCA9IHY0bDJfbTJtX2dldF9jdXJyX3ByaXYoanBl Zy0+bTJtX2Rldik7DQorCWlmICghY3R4KSB7DQorCQl2NGwyX2VycigmanBlZy0+djRsMl9kZXYs ICJDb250ZXh0IGlzIE5VTExcbiIpOw0KKwkJcmV0dXJuIElSUV9IQU5ETEVEOw0KKwl9DQorDQor CXNyY19idWYgPSB2NGwyX20ybV9zcmNfYnVmX3JlbW92ZShjdHgtPmZoLm0ybV9jdHgpOw0KKwlk c3RfYnVmID0gdjRsMl9tMm1fZHN0X2J1Zl9yZW1vdmUoY3R4LT5maC5tMm1fY3R4KTsNCisJanBl Z19zcmNfYnVmID0gbXRrX2pwZWdfdmIyX3RvX3NyY2J1Zigmc3JjX2J1Zi0+dmIyX2J1Zik7DQor DQorCWVuY19yZXQgPSBtdGtfanBlZ19lbmNfZ2V0X2FuZF9jbGVhcl9pbnRfc3RhdHVzKGpwZWct PnJlZ19iYXNlKTsNCisJZW5jX2lycV9yZXQgPSBtdGtfanBlZ19lbmNfZW51bV9yZXN1bHQoanBl Zy0+cmVnX2Jhc2UsIGVuY19yZXQpOw0KKw0KKwlpZiAoZW5jX2lycV9yZXQgPj0gTVRLX0pQRUdf RU5DX1JFU1VMVF9TVEFMTCkNCisJCW10a19qcGVnX2VuY19yZXNldChqcGVnLT5yZWdfYmFzZSk7 DQorDQorCWlmIChlbmNfaXJxX3JldCAhPSBNVEtfSlBFR19FTkNfUkVTVUxUX0RPTkUpIHsNCisJ CWRldl9lcnIoanBlZy0+ZGV2LCAiZW5jb2RlIGZhaWxlZFxuIik7DQorCQlnb3RvIGVuY19lbmQ7 DQorCX0NCisNCisJcmVzdWx0X3NpemUgPSBtdGtfanBlZ19lbmNfZ2V0X2ZpbGVfc2l6ZShqcGVn LT5yZWdfYmFzZSk7DQorCXZiMl9zZXRfcGxhbmVfcGF5bG9hZCgmZHN0X2J1Zi0+dmIyX2J1Ziwg MCwgcmVzdWx0X3NpemUpOw0KKw0KKwlidWZfc3RhdGUgPSBWQjJfQlVGX1NUQVRFX0RPTkU7DQor DQorZW5jX2VuZDoNCisJdjRsMl9tMm1fYnVmX2RvbmUoc3JjX2J1ZiwgYnVmX3N0YXRlKTsNCisJ djRsMl9tMm1fYnVmX2RvbmUoZHN0X2J1ZiwgYnVmX3N0YXRlKTsNCisJdjRsMl9tMm1fam9iX2Zp bmlzaChqcGVnLT5tMm1fZGV2LCBjdHgtPmZoLm0ybV9jdHgpOw0KKwlzcGluX3VubG9jaygmanBl Zy0+aHdfbG9jayk7DQorCXBtX3J1bnRpbWVfcHV0X3N5bmMoY3R4LT5qcGVnLT5kZXYpOw0KKwly ZXR1cm4gSVJRX0hBTkRMRUQ7DQorfQ0KKw0KIHN0YXRpYyBpcnFyZXR1cm5fdCBtdGtfanBlZ19k ZWNfaXJxKGludCBpcnEsIHZvaWQgKnByaXYpDQogew0KIAlzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpq cGVnID0gcHJpdjsNCkBAIC04NzYsMTMgKzEzMzgsMTMgQEAgc3RhdGljIGlycXJldHVybl90IG10 a19qcGVnX2RlY19pcnEoaW50IGlycSwgdm9pZCAqcHJpdikNCiAJc3RydWN0IHZiMl92NGwyX2J1 ZmZlciAqc3JjX2J1ZiwgKmRzdF9idWY7DQogCXN0cnVjdCBtdGtfanBlZ19zcmNfYnVmICpqcGVn X3NyY19idWY7DQogCWVudW0gdmIyX2J1ZmZlcl9zdGF0ZSBidWZfc3RhdGUgPSBWQjJfQlVGX1NU QVRFX0VSUk9SOw0KLQl1MzIJZGVjX2lycV9yZXQ7DQorCXUzMiBkZWNfaXJxX3JldDsNCiAJdTMy IGRlY19yZXQ7DQogCWludCBpOw0KIA0KIAlzcGluX2xvY2soJmpwZWctPmh3X2xvY2spOw0KIA0K LQlkZWNfcmV0ID0gbXRrX2pwZWdfZGVjX2dldF9pbnRfc3RhdHVzKGpwZWctPmRlY19yZWdfYmFz ZSk7DQorCWRlY19yZXQgPSBtdGtfanBlZ19kZWNfZ2V0X2ludF9zdGF0dXMoanBlZy0+cmVnX2Jh c2UpOw0KIAlkZWNfaXJxX3JldCA9IG10a19qcGVnX2RlY19lbnVtX3Jlc3VsdChkZWNfcmV0KTsN CiAJY3R4ID0gdjRsMl9tMm1fZ2V0X2N1cnJfcHJpdihqcGVnLT5tMm1fZGV2KTsNCiAJaWYgKCFj dHgpIHsNCkBAIC04OTUsNyArMTM1Nyw3IEBAIHN0YXRpYyBpcnFyZXR1cm5fdCBtdGtfanBlZ19k ZWNfaXJxKGludCBpcnEsIHZvaWQgKnByaXYpDQogCWpwZWdfc3JjX2J1ZiA9IG10a19qcGVnX3Zi Ml90b19zcmNidWYoJnNyY19idWYtPnZiMl9idWYpOw0KIA0KIAlpZiAoZGVjX2lycV9yZXQgPj0g TVRLX0pQRUdfREVDX1JFU1VMVF9VTkRFUkZMT1cpDQotCQltdGtfanBlZ19kZWNfcmVzZXQoanBl Zy0+ZGVjX3JlZ19iYXNlKTsNCisJCW10a19qcGVnX2RlY19yZXNldChqcGVnLT5yZWdfYmFzZSk7 DQogDQogCWlmIChkZWNfaXJxX3JldCAhPSBNVEtfSlBFR19ERUNfUkVTVUxUX0VPRl9ET05FKSB7 DQogCQlkZXZfZXJyKGpwZWctPmRldiwgImRlY29kZSBmYWlsZWRcbiIpOw0KQEAgLTkxNywzOSAr MTM3OSwxMzEgQEAgc3RhdGljIGlycXJldHVybl90IG10a19qcGVnX2RlY19pcnEoaW50IGlycSwg dm9pZCAqcHJpdikNCiAJcmV0dXJuIElSUV9IQU5ETEVEOw0KIH0NCiANCi1zdGF0aWMgdm9pZCBt dGtfanBlZ19zZXRfZGVmYXVsdF9wYXJhbXMoc3RydWN0IG10a19qcGVnX2N0eCAqY3R4KQ0KK3N0 YXRpYyB2b2lkIG10a19qcGVnX3NldF9lbmNfZGVmYXVsdF9wYXJhbXMoc3RydWN0IG10a19qcGVn X2N0eCAqY3R4KQ0KIHsNCiAJc3RydWN0IG10a19qcGVnX3FfZGF0YSAqcSA9ICZjdHgtPm91dF9x Ow0KLQlpbnQgaTsNCisJc3RydWN0IHY0bDJfcGl4X2Zvcm1hdF9tcGxhbmUgKnBpeF9tcDsNCisN CisJcGl4X21wID0ga21hbGxvYyhzaXplb2YoKnBpeF9tcCksIEdGUF9LRVJORUwpOw0KIA0KKwlj dHgtPmZoLmN0cmxfaGFuZGxlciA9ICZjdHgtPmN0cmxfaGRsOw0KIAljdHgtPmNvbG9yc3BhY2Ug PSBWNEwyX0NPTE9SU1BBQ0VfSlBFRywNCiAJY3R4LT55Y2Jjcl9lbmMgPSBWNEwyX1lDQkNSX0VO Q19ERUZBVUxUOw0KIAljdHgtPnF1YW50aXphdGlvbiA9IFY0TDJfUVVBTlRJWkFUSU9OX0RFRkFV TFQ7DQogCWN0eC0+eGZlcl9mdW5jID0gVjRMMl9YRkVSX0ZVTkNfREVGQVVMVDsNCi0NCi0JcS0+ Zm10ID0gbXRrX2pwZWdfZmluZF9mb3JtYXQoY3R4LCBWNEwyX1BJWF9GTVRfSlBFRywNCi0JCQkJ CSAgICAgIE1US19KUEVHX0ZNVF9UWVBFX09VVFBVVCk7DQotCXEtPncgPSBNVEtfSlBFR19NSU5f V0lEVEg7DQotCXEtPmggPSBNVEtfSlBFR19NSU5fSEVJR0hUOw0KLQlxLT5ieXRlc3BlcmxpbmVb MF0gPSAwOw0KLQlxLT5zaXplaW1hZ2VbMF0gPSBNVEtfSlBFR19ERUZBVUxUX1NJWkVJTUFHRTsN CisJcGl4X21wLT53aWR0aCA9IE1US19KUEVHX01JTl9XSURUSDsNCisJcGl4X21wLT5oZWlnaHQg PSBNVEtfSlBFR19NSU5fSEVJR0hUOw0KKw0KKwlxLT5mbXQgPSBtdGtfanBlZ19maW5kX2Zvcm1h dChWNEwyX1BJWF9GTVRfWVVZViwNCisJCQkJICAgICAgTVRLX0pQRUdfRk1UX0ZMQUdfRU5DX09V VFBVVCk7DQorCXZpZGlvY190cnlfZm10KGNvbnRhaW5lcl9vZihwaXhfbXAsIHN0cnVjdCB2NGwy X2Zvcm1hdCwNCisJCQkJICAgIGZtdC5waXhfbXApLCBxLT5mbXQpOw0KKwlxLT53ID0gcGl4X21w LT53aWR0aDsNCisJcS0+aCA9IHBpeF9tcC0+aGVpZ2h0Ow0KKwlxLT5zaXplaW1hZ2VbMF0gPSBw aXhfbXAtPnBsYW5lX2ZtdFswXS5zaXplaW1hZ2U7DQorCXEtPmJ5dGVzcGVybGluZVswXSA9IHBp eF9tcC0+cGxhbmVfZm10WzBdLmJ5dGVzcGVybGluZTsNCiANCiAJcSA9ICZjdHgtPmNhcF9xOw0K LQlxLT5mbXQgPSBtdGtfanBlZ19maW5kX2Zvcm1hdChjdHgsIFY0TDJfUElYX0ZNVF9ZVVY0MjBN LA0KLQkJCQkJICAgICAgTVRLX0pQRUdfRk1UX1RZUEVfQ0FQVFVSRSk7DQotCXEtPncgPSBNVEtf SlBFR19NSU5fV0lEVEg7DQotCXEtPmggPSBNVEtfSlBFR19NSU5fSEVJR0hUOw0KKwlxLT5mbXQg PSBtdGtfanBlZ19maW5kX2Zvcm1hdChWNEwyX1BJWF9GTVRfSlBFRywNCisJCQkJICAgICAgTVRL X0pQRUdfRk1UX0ZMQUdfRU5DX0NBUFRVUkUpOw0KKwlwaXhfbXAtPndpZHRoID0gTVRLX0pQRUdf TUlOX1dJRFRIOw0KKwlwaXhfbXAtPmhlaWdodCA9IE1US19KUEVHX01JTl9IRUlHSFQ7DQorCXZp ZGlvY190cnlfZm10KGNvbnRhaW5lcl9vZihwaXhfbXAsIHN0cnVjdCB2NGwyX2Zvcm1hdCwNCisJ CQkJICAgIGZtdC5waXhfbXApLCBxLT5mbXQpOw0KKwlxLT53ID0gcGl4X21wLT53aWR0aDsNCisJ cS0+aCA9IHBpeF9tcC0+aGVpZ2h0Ow0KKwlxLT5zaXplaW1hZ2VbMF0gPSBwaXhfbXAtPnBsYW5l X2ZtdFswXS5zaXplaW1hZ2U7DQorCXEtPmJ5dGVzcGVybGluZVswXSA9IHBpeF9tcC0+cGxhbmVf Zm10WzBdLmJ5dGVzcGVybGluZTsNCit9DQorDQorc3RhdGljIHZvaWQgbXRrX2pwZWdfc2V0X2Rl Y19kZWZhdWx0X3BhcmFtcyhzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgpDQorew0KKwlzdHJ1Y3Qg bXRrX2pwZWdfcV9kYXRhICpxID0gJmN0eC0+b3V0X3E7DQorCXN0cnVjdCB2NGwyX3BpeF9mb3Jt YXRfbXBsYW5lICpwaXhfbXA7DQorCWludCBpOw0KKw0KKwlwaXhfbXAgPSBrbWFsbG9jKHNpemVv ZigqcGl4X21wKSwgR0ZQX0tFUk5FTCk7DQogDQorCWN0eC0+ZmguY3RybF9oYW5kbGVyID0gJmN0 eC0+Y3RybF9oZGw7DQorCWN0eC0+Y29sb3JzcGFjZSA9IFY0TDJfQ09MT1JTUEFDRV9KUEVHLA0K KwljdHgtPnljYmNyX2VuYyA9IFY0TDJfWUNCQ1JfRU5DX0RFRkFVTFQ7DQorCWN0eC0+cXVhbnRp emF0aW9uID0gVjRMMl9RVUFOVElaQVRJT05fREVGQVVMVDsNCisJY3R4LT54ZmVyX2Z1bmMgPSBW NEwyX1hGRVJfRlVOQ19ERUZBVUxUOw0KKwlwaXhfbXAtPndpZHRoID0gTVRLX0pQRUdfTUlOX1dJ RFRIOw0KKwlwaXhfbXAtPmhlaWdodCA9IE1US19KUEVHX01JTl9IRUlHSFQ7DQorDQorCXEtPmZt dCA9IG10a19qcGVnX2ZpbmRfZm9ybWF0KFY0TDJfUElYX0ZNVF9KUEVHLA0KKwkJCQkgICAgICBN VEtfSlBFR19GTVRfRkxBR19ERUNfT1VUUFVUKTsNCisJdmlkaW9jX3RyeV9mbXQoY29udGFpbmVy X29mKHBpeF9tcCwgc3RydWN0IHY0bDJfZm9ybWF0LA0KKwkJCQkgICAgZm10LnBpeF9tcCksIHEt PmZtdCk7DQorCXEtPncgPSBwaXhfbXAtPndpZHRoOw0KKwlxLT5oID0gcGl4X21wLT5oZWlnaHQ7 DQorCXEtPnNpemVpbWFnZVswXSA9IHBpeF9tcC0+cGxhbmVfZm10WzBdLnNpemVpbWFnZTsNCisJ cS0+Ynl0ZXNwZXJsaW5lWzBdID0gcGl4X21wLT5wbGFuZV9mbXRbMF0uYnl0ZXNwZXJsaW5lOw0K Kw0KKwlxID0gJmN0eC0+Y2FwX3E7DQorCXEtPmZtdCA9IG10a19qcGVnX2ZpbmRfZm9ybWF0KFY0 TDJfUElYX0ZNVF9ZVVY0MjBNLA0KKwkJCQkgICAgICBNVEtfSlBFR19GTVRfRkxBR19ERUNfQ0FQ VFVSRSk7DQorCXBpeF9tcC0+d2lkdGggPSBNVEtfSlBFR19NSU5fV0lEVEg7DQorCXBpeF9tcC0+ aGVpZ2h0ID0gTVRLX0pQRUdfTUlOX0hFSUdIVDsNCisJdmlkaW9jX3RyeV9mbXQoY29udGFpbmVy X29mKHBpeF9tcCwgc3RydWN0IHY0bDJfZm9ybWF0LA0KKwkJCQkgICAgZm10LnBpeF9tcCksIHEt PmZtdCk7DQorCXEtPncgPSBwaXhfbXAtPndpZHRoOw0KKwlxLT5oID0gcGl4X21wLT5oZWlnaHQ7 DQogCWZvciAoaSA9IDA7IGkgPCBxLT5mbXQtPmNvbHBsYW5lczsgaSsrKSB7DQotCQl1MzIgc3Ry aWRlID0gcS0+dyAqIHEtPmZtdC0+aF9zYW1wbGVbaV0gLyA0Ow0KLQkJdTMyIGggPSBxLT5oICog cS0+Zm10LT52X3NhbXBsZVtpXSAvIDQ7DQorCQlxLT5zaXplaW1hZ2VbaV0gPSBwaXhfbXAtPnBs YW5lX2ZtdFtpXS5zaXplaW1hZ2U7DQorCQlxLT5ieXRlc3BlcmxpbmVbaV0gPSBwaXhfbXAtPnBs YW5lX2ZtdFtpXS5ieXRlc3BlcmxpbmU7DQorCX0NCit9DQorDQorc3RhdGljIGludCBtdGtfanBl Z19lbmNfb3BlbihzdHJ1Y3QgZmlsZSAqZmlsZSkNCit7DQorCXN0cnVjdCBtdGtfanBlZ19kZXYg KmpwZWcgPSB2aWRlb19kcnZkYXRhKGZpbGUpOw0KKwlzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZmQg PSB2aWRlb19kZXZkYXRhKGZpbGUpOw0KKwlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHg7DQorCWlu dCByZXQgPSAwOw0KIA0KLQkJcS0+Ynl0ZXNwZXJsaW5lW2ldID0gc3RyaWRlOw0KLQkJcS0+c2l6 ZWltYWdlW2ldID0gc3RyaWRlICogaDsNCisJY3R4ID0ga3phbGxvYyhzaXplb2YoKmN0eCksIEdG UF9LRVJORUwpOw0KKwlpZiAoIWN0eCkNCisJCXJldHVybiAtRU5PTUVNOw0KKw0KKwlpZiAobXV0 ZXhfbG9ja19pbnRlcnJ1cHRpYmxlKCZqcGVnLT5sb2NrKSkgew0KKwkJcmV0ID0gLUVSRVNUQVJU U1lTOw0KKwkJZ290byBmcmVlOw0KKwl9DQorDQorCXY0bDJfZmhfaW5pdCgmY3R4LT5maCwgdmZk KTsNCisJZmlsZS0+cHJpdmF0ZV9kYXRhID0gJmN0eC0+Zmg7DQorCXY0bDJfZmhfYWRkKCZjdHgt PmZoKTsNCisNCisJY3R4LT5qcGVnID0ganBlZzsNCisJY3R4LT5maC5tMm1fY3R4ID0gdjRsMl9t Mm1fY3R4X2luaXQoanBlZy0+bTJtX2RldiwgY3R4LA0KKwkJCQkJICAgIG10a19qcGVnX2VuY19x dWV1ZV9pbml0KTsNCisJaWYgKElTX0VSUihjdHgtPmZoLm0ybV9jdHgpKSB7DQorCQlyZXQgPSBQ VFJfRVJSKGN0eC0+ZmgubTJtX2N0eCk7DQorCQlnb3RvIGVycm9yOw0KIAl9DQorDQorCXJldCA9 IG10a19qcGVnX2VuY19jdHJsc19zZXR1cChjdHgpOw0KKwlpZiAocmV0KSB7DQorCQl2NGwyX2Vy cigmanBlZy0+djRsMl9kZXYsICJGYWlsZWQgdG8gc2V0dXAganBlZyBlbmMgY29udHJvbHNcbiIp Ow0KKwkJZ290byBlcnJvcjsNCisJfQ0KKwltdGtfanBlZ19zZXRfZW5jX2RlZmF1bHRfcGFyYW1z KGN0eCk7DQorDQorCW11dGV4X3VubG9jaygmanBlZy0+bG9jayk7DQorCXJldHVybiAwOw0KKw0K K2Vycm9yOg0KKwl2NGwyX2ZoX2RlbCgmY3R4LT5maCk7DQorCXY0bDJfZmhfZXhpdCgmY3R4LT5m aCk7DQorCW11dGV4X3VubG9jaygmanBlZy0+bG9jayk7DQorZnJlZToNCisJa2ZyZWUoY3R4KTsN CisJcmV0dXJuIHJldDsNCiB9DQogDQotc3RhdGljIGludCBtdGtfanBlZ19vcGVuKHN0cnVjdCBm aWxlICpmaWxlKQ0KK3N0YXRpYyBpbnQgbXRrX2pwZWdfZGVjX29wZW4oc3RydWN0IGZpbGUgKmZp bGUpDQogew0KIAlzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpqcGVnID0gdmlkZW9fZHJ2ZGF0YShmaWxl KTsNCiAJc3RydWN0IHZpZGVvX2RldmljZSAqdmZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsNCkBA IC05NzEsMTMgKzE1MjUsMjAgQEAgc3RhdGljIGludCBtdGtfanBlZ19vcGVuKHN0cnVjdCBmaWxl ICpmaWxlKQ0KIA0KIAljdHgtPmpwZWcgPSBqcGVnOw0KIAljdHgtPmZoLm0ybV9jdHggPSB2NGwy X20ybV9jdHhfaW5pdChqcGVnLT5tMm1fZGV2LCBjdHgsDQotCQkJCQkgICAgbXRrX2pwZWdfcXVl dWVfaW5pdCk7DQorCQkJCQkgICAgbXRrX2pwZWdfZGVjX3F1ZXVlX2luaXQpOw0KIAlpZiAoSVNf RVJSKGN0eC0+ZmgubTJtX2N0eCkpIHsNCiAJCXJldCA9IFBUUl9FUlIoY3R4LT5maC5tMm1fY3R4 KTsNCiAJCWdvdG8gZXJyb3I7DQogCX0NCiANCi0JbXRrX2pwZWdfc2V0X2RlZmF1bHRfcGFyYW1z KGN0eCk7DQorCXY0bDJfY3RybF9oYW5kbGVyX2luaXQoJmN0eC0+Y3RybF9oZGwsIDApOw0KKwly ZXQgPSB2NGwyX2N0cmxfaGFuZGxlcl9zZXR1cCgmY3R4LT5jdHJsX2hkbCk7DQorCWlmIChyZXQp IHsNCisJCXY0bDJfZXJyKCZqcGVnLT52NGwyX2RldiwgIkZhaWxlZCB0byBzZXR1cCBqcGVnIGRl YyBjb250cm9sc1xuIik7DQorCQlnb3RvIGVycm9yOw0KKwl9DQorCW10a19qcGVnX3NldF9kZWNf ZGVmYXVsdF9wYXJhbXMoY3R4KTsNCisNCiAJbXV0ZXhfdW5sb2NrKCZqcGVnLT5sb2NrKTsNCiAJ cmV0dXJuIDA7DQogDQpAQCAtOTk3LDYgKzE1NTgsNyBAQCBzdGF0aWMgaW50IG10a19qcGVnX3Jl bGVhc2Uoc3RydWN0IGZpbGUgKmZpbGUpDQogDQogCW11dGV4X2xvY2soJmpwZWctPmxvY2spOw0K IAl2NGwyX20ybV9jdHhfcmVsZWFzZShjdHgtPmZoLm0ybV9jdHgpOw0KKwl2NGwyX2N0cmxfaGFu ZGxlcl9mcmVlKCZjdHgtPmN0cmxfaGRsKTsNCiAJdjRsMl9maF9kZWwoJmN0eC0+ZmgpOw0KIAl2 NGwyX2ZoX2V4aXQoJmN0eC0+ZmgpOw0KIAlrZnJlZShjdHgpOw0KQEAgLTEwMDQsOSArMTU2Niwx OCBAQCBzdGF0aWMgaW50IG10a19qcGVnX3JlbGVhc2Uoc3RydWN0IGZpbGUgKmZpbGUpDQogCXJl dHVybiAwOw0KIH0NCiANCi1zdGF0aWMgY29uc3Qgc3RydWN0IHY0bDJfZmlsZV9vcGVyYXRpb25z IG10a19qcGVnX2ZvcHMgPSB7DQorc3RhdGljIGNvbnN0IHN0cnVjdCB2NGwyX2ZpbGVfb3BlcmF0 aW9ucyBtdGtfanBlZ19lbmNfZm9wcyA9IHsNCiAJLm93bmVyICAgICAgICAgID0gVEhJU19NT0RV TEUsDQotCS5vcGVuICAgICAgICAgICA9IG10a19qcGVnX29wZW4sDQorCS5vcGVuICAgICAgICAg ICA9IG10a19qcGVnX2VuY19vcGVuLA0KKwkucmVsZWFzZSAgICAgICAgPSBtdGtfanBlZ19yZWxl YXNlLA0KKwkucG9sbCAgICAgICAgICAgPSB2NGwyX20ybV9mb3BfcG9sbCwNCisJLnVubG9ja2Vk X2lvY3RsID0gdmlkZW9faW9jdGwyLA0KKwkubW1hcCAgICAgICAgICAgPSB2NGwyX20ybV9mb3Bf bW1hcCwNCit9Ow0KKw0KK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdjRsMl9maWxlX29wZXJhdGlvbnMg bXRrX2pwZWdfZGVjX2ZvcHMgPSB7DQorCS5vd25lciAgICAgICAgICA9IFRISVNfTU9EVUxFLA0K Kwkub3BlbiAgICAgICAgICAgPSBtdGtfanBlZ19kZWNfb3BlbiwNCiAJLnJlbGVhc2UgICAgICAg ID0gbXRrX2pwZWdfcmVsZWFzZSwNCiAJLnBvbGwgICAgICAgICAgID0gdjRsMl9tMm1fZm9wX3Bv bGwsDQogCS51bmxvY2tlZF9pb2N0bCA9IHZpZGVvX2lvY3RsMiwNCkBAIC0xMDE3LDYgKzE1ODgs NyBAQCBzdGF0aWMgaW50IG10a19qcGVnX2Nsa19pbml0KHN0cnVjdCBtdGtfanBlZ19kZXYgKmpw ZWcpDQogew0KIAlzdHJ1Y3QgZGV2aWNlX25vZGUgKm5vZGU7DQogCXN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKnBkZXY7DQorCWludCBpOw0KIA0KIAlub2RlID0gb2ZfcGFyc2VfcGhhbmRsZShqcGVn LT5kZXYtPm9mX25vZGUsICJtZWRpYXRlayxsYXJiIiwgMCk7DQogCWlmICghbm9kZSkNCkBAIC0x MDMwLDE5ICsxNjAyLDI0IEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfY2xrX2luaXQoc3RydWN0IG10 a19qcGVnX2RldiAqanBlZykNCiANCiAJanBlZy0+bGFyYiA9ICZwZGV2LT5kZXY7DQogDQotCWpw ZWctPmNsa19qZGVjID0gZGV2bV9jbGtfZ2V0KGpwZWctPmRldiwgImpwZ2RlYyIpOw0KLQlpZiAo SVNfRVJSKGpwZWctPmNsa19qZGVjKSkNCi0JCXJldHVybiBQVFJfRVJSKGpwZWctPmNsa19qZGVj KTsNCisJZm9yIChpID0gMDsgaSA8IGpwZWctPnZhcmlhbnQtPm51bV9jbG9ja3M7IGkrKykgew0K KwkJanBlZy0+Y2xvY2tzW2ldID0gZGV2bV9jbGtfZ2V0KGpwZWctPmRldiwNCisJCQkJCSAgICAg ICBqcGVnLT52YXJpYW50LT5jbGtfbmFtZXNbaV0pOw0KKwkJaWYgKElTX0VSUihqcGVnLT5jbG9j a3NbaV0pKSB7DQorCQkJZGV2X2VycigmcGRldi0+ZGV2LCAiZmFpbGVkIHRvIGdldCBjbG9jazog JXNcbiIsDQorCQkJCWpwZWctPnZhcmlhbnQtPmNsa19uYW1lc1tpXSk7DQorCQkJcmV0dXJuIFBU Ul9FUlIoanBlZy0+Y2xvY2tzW2ldKTsNCisJCX0NCisJfQ0KIA0KLQlqcGVnLT5jbGtfamRlY19z bWkgPSBkZXZtX2Nsa19nZXQoanBlZy0+ZGV2LCAianBnZGVjLXNtaSIpOw0KLQlyZXR1cm4gUFRS X0VSUl9PUl9aRVJPKGpwZWctPmNsa19qZGVjX3NtaSk7DQorCXJldHVybiAwOw0KIH0NCiANCiBz dGF0aWMgaW50IG10a19qcGVnX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQog ew0KIAlzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpqcGVnOw0KIAlzdHJ1Y3QgcmVzb3VyY2UgKnJlczsN Ci0JaW50IGRlY19pcnE7DQorCWludCBqcGVnX2lycTsNCiAJaW50IHJldDsNCiANCiAJanBlZyA9 IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCBzaXplb2YoKmpwZWcpLCBHRlBfS0VSTkVMKTsNCkBA IC0xMDUyLDI1ICsxNjI5LDMwIEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfcHJvYmUoc3RydWN0IHBs YXRmb3JtX2RldmljZSAqcGRldikNCiAJbXV0ZXhfaW5pdCgmanBlZy0+bG9jayk7DQogCXNwaW5f bG9ja19pbml0KCZqcGVnLT5od19sb2NrKTsNCiAJanBlZy0+ZGV2ID0gJnBkZXYtPmRldjsNCisJ anBlZy0+dmFyaWFudCA9IG9mX2RldmljZV9nZXRfbWF0Y2hfZGF0YShqcGVnLT5kZXYpOw0KIA0K IAlyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOw0K LQlqcGVnLT5kZWNfcmVnX2Jhc2UgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoJnBkZXYtPmRldiwg cmVzKTsNCi0JaWYgKElTX0VSUihqcGVnLT5kZWNfcmVnX2Jhc2UpKSB7DQotCQlyZXQgPSBQVFJf RVJSKGpwZWctPmRlY19yZWdfYmFzZSk7DQorCWpwZWctPnJlZ19iYXNlID0gZGV2bV9pb3JlbWFw X3Jlc291cmNlKCZwZGV2LT5kZXYsIHJlcyk7DQorCWlmIChJU19FUlIoanBlZy0+cmVnX2Jhc2Up KSB7DQorCQlyZXQgPSBQVFJfRVJSKGpwZWctPnJlZ19iYXNlKTsNCiAJCXJldHVybiByZXQ7DQog CX0NCiANCi0JZGVjX2lycSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7DQotCWlmIChkZWNf aXJxIDwgMCkgew0KLQkJZGV2X2VycigmcGRldi0+ZGV2LCAiRmFpbGVkIHRvIGdldCBkZWNfaXJx ICVkLlxuIiwgZGVjX2lycSk7DQotCQlyZXR1cm4gZGVjX2lycTsNCisJanBlZ19pcnEgPSBwbGF0 Zm9ybV9nZXRfaXJxKHBkZXYsIDApOw0KKwlpZiAoanBlZ19pcnEgPCAwKSB7DQorCQlkZXZfZXJy KCZwZGV2LT5kZXYsICJGYWlsZWQgdG8gZ2V0IGpwZWdfaXJxICVkLlxuIiwganBlZ19pcnEpOw0K KwkJcmV0dXJuIGpwZWdfaXJxOw0KIAl9DQogDQotCXJldCA9IGRldm1fcmVxdWVzdF9pcnEoJnBk ZXYtPmRldiwgZGVjX2lycSwgbXRrX2pwZWdfZGVjX2lycSwgMCwNCi0JCQkgICAgICAgcGRldi0+ bmFtZSwganBlZyk7DQorCWlmIChqcGVnLT52YXJpYW50LT5pc19lbmNvZGVyKQ0KKwkJcmV0ID0g ZGV2bV9yZXF1ZXN0X2lycSgmcGRldi0+ZGV2LCBqcGVnX2lycSwgbXRrX2pwZWdfZW5jX2lycSwN CisJCQkJICAgICAgIDAsIHBkZXYtPm5hbWUsIGpwZWcpOw0KKwllbHNlDQorCQlyZXQgPSBkZXZt X3JlcXVlc3RfaXJxKCZwZGV2LT5kZXYsIGpwZWdfaXJxLCBtdGtfanBlZ19kZWNfaXJxLA0KKwkJ CQkgICAgICAgMCwgcGRldi0+bmFtZSwganBlZyk7DQogCWlmIChyZXQpIHsNCi0JCWRldl9lcnIo JnBkZXYtPmRldiwgIkZhaWxlZCB0byByZXF1ZXN0IGRlY19pcnEgJWQgKCVkKVxuIiwNCi0JCQlk ZWNfaXJxLCByZXQpOw0KKwkJZGV2X2VycigmcGRldi0+ZGV2LCAiRmFpbGVkIHRvIHJlcXVlc3Qg anBlZ19pcnEgJWQgKCVkKVxuIiwNCisJCQlqcGVnX2lycSwgcmV0KTsNCiAJCWdvdG8gZXJyX3Jl cV9pcnE7DQogCX0NCiANCkBAIC0xMDg3LDQwICsxNjY5LDUwIEBAIHN0YXRpYyBpbnQgbXRrX2pw ZWdfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCiAJCWdvdG8gZXJyX2Rldl9y ZWdpc3RlcjsNCiAJfQ0KIA0KLQlqcGVnLT5tMm1fZGV2ID0gdjRsMl9tMm1faW5pdCgmbXRrX2pw ZWdfbTJtX29wcyk7DQorCWlmIChqcGVnLT52YXJpYW50LT5pc19lbmNvZGVyKQ0KKwkJanBlZy0+ bTJtX2RldiA9IHY0bDJfbTJtX2luaXQoJm10a19qcGVnX2VuY19tMm1fb3BzKTsNCisJZWxzZQ0K KwkJanBlZy0+bTJtX2RldiA9IHY0bDJfbTJtX2luaXQoJm10a19qcGVnX2RlY19tMm1fb3BzKTsN CiAJaWYgKElTX0VSUihqcGVnLT5tMm1fZGV2KSkgew0KIAkJdjRsMl9lcnIoJmpwZWctPnY0bDJf ZGV2LCAiRmFpbGVkIHRvIGluaXQgbWVtMm1lbSBkZXZpY2VcbiIpOw0KIAkJcmV0ID0gUFRSX0VS UihqcGVnLT5tMm1fZGV2KTsNCiAJCWdvdG8gZXJyX20ybV9pbml0Ow0KIAl9DQogDQotCWpwZWct PmRlY192ZGV2ID0gdmlkZW9fZGV2aWNlX2FsbG9jKCk7DQotCWlmICghanBlZy0+ZGVjX3ZkZXYp IHsNCisJanBlZy0+dmRldiA9IHZpZGVvX2RldmljZV9hbGxvYygpOw0KKwlpZiAoIWpwZWctPnZk ZXYpIHsNCiAJCXJldCA9IC1FTk9NRU07DQotCQlnb3RvIGVycl9kZWNfdmRldl9hbGxvYzsNCisJ CWdvdG8gZXJyX3ZmZF9qcGVnX2FsbG9jOw0KIAl9DQotCXNucHJpbnRmKGpwZWctPmRlY192ZGV2 LT5uYW1lLCBzaXplb2YoanBlZy0+ZGVjX3ZkZXYtPm5hbWUpLA0KLQkJICIlcy1kZWMiLCBNVEtf SlBFR19OQU1FKTsNCi0JanBlZy0+ZGVjX3ZkZXYtPmZvcHMgPSAmbXRrX2pwZWdfZm9wczsNCi0J anBlZy0+ZGVjX3ZkZXYtPmlvY3RsX29wcyA9ICZtdGtfanBlZ19pb2N0bF9vcHM7DQotCWpwZWct PmRlY192ZGV2LT5taW5vciA9IC0xOw0KLQlqcGVnLT5kZWNfdmRldi0+cmVsZWFzZSA9IHZpZGVv X2RldmljZV9yZWxlYXNlOw0KLQlqcGVnLT5kZWNfdmRldi0+bG9jayA9ICZqcGVnLT5sb2NrOw0K LQlqcGVnLT5kZWNfdmRldi0+djRsMl9kZXYgPSAmanBlZy0+djRsMl9kZXY7DQotCWpwZWctPmRl Y192ZGV2LT52ZmxfZGlyID0gVkZMX0RJUl9NMk07DQotCWpwZWctPmRlY192ZGV2LT5kZXZpY2Vf Y2FwcyA9IFY0TDJfQ0FQX1NUUkVBTUlORyB8DQorCXNucHJpbnRmKGpwZWctPnZkZXYtPm5hbWUs IHNpemVvZihqcGVnLT52ZGV2LT5uYW1lKSwNCisJCSAiJXMtJXMiLCBNVEtfSlBFR19OQU1FLA0K KwkJIGpwZWctPnZhcmlhbnQtPmlzX2VuY29kZXIgPyAiZW5jIiA6ICJkZWMiKTsNCisJaWYgKGpw ZWctPnZhcmlhbnQtPmlzX2VuY29kZXIpIHsNCisJCWpwZWctPnZkZXYtPmZvcHMgPSAmbXRrX2pw ZWdfZW5jX2ZvcHM7DQorCQlqcGVnLT52ZGV2LT5pb2N0bF9vcHMgPSAmbXRrX2pwZWdfZW5jX2lv Y3RsX29wczsNCisJfSBlbHNlIHsNCisJCWpwZWctPnZkZXYtPmZvcHMgPSAmbXRrX2pwZWdfZGVj X2ZvcHM7DQorCQlqcGVnLT52ZGV2LT5pb2N0bF9vcHMgPSAmbXRrX2pwZWdfZGVjX2lvY3RsX29w czsNCisJfQ0KKwlqcGVnLT52ZGV2LT5taW5vciA9IC0xOw0KKwlqcGVnLT52ZGV2LT5yZWxlYXNl ID0gdmlkZW9fZGV2aWNlX3JlbGVhc2U7DQorCWpwZWctPnZkZXYtPmxvY2sgPSAmanBlZy0+bG9j azsNCisJanBlZy0+dmRldi0+djRsMl9kZXYgPSAmanBlZy0+djRsMl9kZXY7DQorCWpwZWctPnZk ZXYtPnZmbF9kaXIgPSBWRkxfRElSX00yTTsNCisJanBlZy0+dmRldi0+ZGV2aWNlX2NhcHMgPSBW NEwyX0NBUF9TVFJFQU1JTkcgfA0KIAkJCQkgICAgICBWNEwyX0NBUF9WSURFT19NMk1fTVBMQU5F Ow0KIA0KLQlyZXQgPSB2aWRlb19yZWdpc3Rlcl9kZXZpY2UoanBlZy0+ZGVjX3ZkZXYsIFZGTF9U WVBFX0dSQUJCRVIsIC0xKTsNCisJcmV0ID0gdmlkZW9fcmVnaXN0ZXJfZGV2aWNlKGpwZWctPnZk ZXYsIFZGTF9UWVBFX0dSQUJCRVIsIC0xKTsNCiAJaWYgKHJldCkgew0KIAkJdjRsMl9lcnIoJmpw ZWctPnY0bDJfZGV2LCAiRmFpbGVkIHRvIHJlZ2lzdGVyIHZpZGVvIGRldmljZVxuIik7DQotCQln b3RvIGVycl9kZWNfdmRldl9yZWdpc3RlcjsNCisJCWdvdG8gZXJyX3ZmZF9qcGVnX3JlZ2lzdGVy Ow0KIAl9DQogDQotCXZpZGVvX3NldF9kcnZkYXRhKGpwZWctPmRlY192ZGV2LCBqcGVnKTsNCisJ dmlkZW9fc2V0X2RydmRhdGEoanBlZy0+dmRldiwganBlZyk7DQogCXY0bDJfaW5mbygmanBlZy0+ djRsMl9kZXYsDQotCQkgICJkZWNvZGVyIGRldmljZSByZWdpc3RlcmVkIGFzIC9kZXYvdmlkZW8l ZCAoJWQsJWQpXG4iLA0KLQkJICBqcGVnLT5kZWNfdmRldi0+bnVtLCBWSURFT19NQUpPUiwganBl Zy0+ZGVjX3ZkZXYtPm1pbm9yKTsNCisJCSAgImpwZWcgJXMgZGV2aWNlIHJlZ2lzdGVyZWQgYXMg L2Rldi92aWRlbyVkICglZCwlZClcbiIsDQorCQkgIGpwZWctPnZhcmlhbnQtPmlzX2VuY29kZXIg PyAiZW5jIiA6ICJkZWMiLCBqcGVnLT52ZGV2LT5udW0sDQorCQkgIFZJREVPX01BSk9SLCBqcGVn LT52ZGV2LT5taW5vcik7DQogDQogCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGpwZWcpOw0K IA0KQEAgLTExMjgsMTAgKzE3MjAsMTAgQEAgc3RhdGljIGludCBtdGtfanBlZ19wcm9iZShzdHJ1 Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KIA0KIAlyZXR1cm4gMDsNCiANCi1lcnJfZGVjX3Zk ZXZfcmVnaXN0ZXI6DQotCXZpZGVvX2RldmljZV9yZWxlYXNlKGpwZWctPmRlY192ZGV2KTsNCitl cnJfdmZkX2pwZWdfcmVnaXN0ZXI6DQorCXZpZGVvX2RldmljZV9yZWxlYXNlKGpwZWctPnZkZXYp Ow0KIA0KLWVycl9kZWNfdmRldl9hbGxvYzoNCitlcnJfdmZkX2pwZWdfYWxsb2M6DQogCXY0bDJf bTJtX3JlbGVhc2UoanBlZy0+bTJtX2Rldik7DQogDQogZXJyX20ybV9pbml0Og0KQEAgLTExNTEs OCArMTc0Myw4IEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKnBkZXYpDQogCXN0cnVjdCBtdGtfanBlZ19kZXYgKmpwZWcgPSBwbGF0Zm9ybV9nZXRf ZHJ2ZGF0YShwZGV2KTsNCiANCiAJcG1fcnVudGltZV9kaXNhYmxlKCZwZGV2LT5kZXYpOw0KLQl2 aWRlb191bnJlZ2lzdGVyX2RldmljZShqcGVnLT5kZWNfdmRldik7DQotCXZpZGVvX2RldmljZV9y ZWxlYXNlKGpwZWctPmRlY192ZGV2KTsNCisJdmlkZW9fdW5yZWdpc3Rlcl9kZXZpY2UoanBlZy0+ dmRldik7DQorCXZpZGVvX2RldmljZV9yZWxlYXNlKGpwZWctPnZkZXYpOw0KIAl2NGwyX20ybV9y ZWxlYXNlKGpwZWctPm0ybV9kZXYpOw0KIAl2NGwyX2RldmljZV91bnJlZ2lzdGVyKCZqcGVnLT52 NGwyX2Rldik7DQogDQpAQCAtMTIxMSwxNCArMTgwMywzNiBAQCBzdGF0aWMgY29uc3Qgc3RydWN0 IGRldl9wbV9vcHMgbXRrX2pwZWdfcG1fb3BzID0gew0KIAlTRVRfUlVOVElNRV9QTV9PUFMobXRr X2pwZWdfcG1fc3VzcGVuZCwgbXRrX2pwZWdfcG1fcmVzdW1lLCBOVUxMKQ0KIH07DQogDQorc3Rh dGljIHN0cnVjdCBtdGtfanBlZ192YXJpYW50IG10ODE3M19qcGVnX2RydmRhdGEgPSB7DQorCS5p c19lbmNvZGVyCT0gZmFsc2UsDQorCS5jbGtfbmFtZXMJPSB7ImpwZ2RlYy1zbWkiLCAianBnZGVj In0sDQorCS5udW1fY2xvY2tzCT0gMiwNCit9Ow0KKw0KK3N0YXRpYyBzdHJ1Y3QgbXRrX2pwZWdf dmFyaWFudCBtdDI3MDFfanBlZ19kcnZkYXRhID0gew0KKwkuaXNfZW5jb2Rlcgk9IGZhbHNlLA0K KwkuY2xrX25hbWVzCT0geyJqcGdkZWMtc21pIiwgImpwZ2RlYyJ9LA0KKwkubnVtX2Nsb2Nrcwk9 IDIsDQorfTsNCisNCitzdGF0aWMgc3RydWN0IG10a19qcGVnX3ZhcmlhbnQgbXRrX2pwZWdfZHJ2 ZGF0YSA9IHsNCisJLmlzX2VuY29kZXIJPSB0cnVlLA0KKwkuY2xrX25hbWVzCT0geyJqcGdlbmMi fSwNCisJLm51bV9jbG9ja3MJPSAxLA0KK307DQorDQogc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9k ZXZpY2VfaWQgbXRrX2pwZWdfbWF0Y2hbXSA9IHsNCiAJew0KIAkJLmNvbXBhdGlibGUgPSAibWVk aWF0ZWssbXQ4MTczLWpwZ2RlYyIsDQotCQkuZGF0YSAgICAgICA9IE5VTEwsDQorCQkuZGF0YSA9 ICZtdDgxNzNfanBlZ19kcnZkYXRhLA0KIAl9LA0KIAl7DQogCQkuY29tcGF0aWJsZSA9ICJtZWRp YXRlayxtdDI3MDEtanBnZGVjIiwNCi0JCS5kYXRhICAgICAgID0gTlVMTCwNCisJCS5kYXRhID0g Jm10MjcwMV9qcGVnX2RydmRhdGEsDQorCX0sDQorCXsNCisJCS5jb21wYXRpYmxlID0gIm1lZGlh dGVrLG10ay1qcGdlbmMiLA0KKwkJLmRhdGEgPSAmbXRrX2pwZWdfZHJ2ZGF0YSwNCiAJfSwNCiAJ e30sDQogfTsNCmRpZmYgLS1naXQgYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210 a19qcGVnX2NvcmUuaCBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdf Y29yZS5oDQppbmRleCA5YmJkNjE1YjEwNjcuLjhmODBmMmE2OWQ0NSAxMDA2NDQNCi0tLSBhL2Ry aXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfY29yZS5oDQorKysgYi9kcml2 ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVnX2NvcmUuaA0KQEAgLTMsNiArMyw3 IEBADQogICogQ29weXJpZ2h0IChjKSAyMDE2IE1lZGlhVGVrIEluYy4NCiAgKiBBdXRob3I6IE1p bmcgSHNpdSBUc2FpIDxtaW5naHNpdS50c2FpQG1lZGlhdGVrLmNvbT4NCiAgKiAgICAgICAgIFJp Y2sgQ2hhbmcgPHJpY2suY2hhbmdAbWVkaWF0ZWsuY29tPg0KKyAqICAgICAgICAgWGlhIEppYW5n IDx4aWEuamlhbmdAbWVkaWF0ZWsuY29tPg0KICAqLw0KIA0KICNpZm5kZWYgX01US19KUEVHX0NP UkVfSA0KQEAgLTE2LDE5ICsxNywyMSBAQA0KICNkZWZpbmUgTVRLX0pQRUdfTkFNRQkJIm10ay1q cGVnIg0KIA0KICNkZWZpbmUgTVRLX0pQRUdfQ09NUF9NQVgJCTMNCisjZGVmaW5lIE1US19KUEVH X01BWF9DTE9DS1MJCTINCisNCiANCiAjZGVmaW5lIE1US19KUEVHX0ZNVF9GTEFHX0RFQ19PVVRQ VVQJQklUKDApDQogI2RlZmluZSBNVEtfSlBFR19GTVRfRkxBR19ERUNfQ0FQVFVSRQlCSVQoMSkN Ci0NCi0jZGVmaW5lIE1US19KUEVHX0ZNVF9UWVBFX09VVFBVVAkxDQotI2RlZmluZSBNVEtfSlBF R19GTVRfVFlQRV9DQVBUVVJFCTINCisjZGVmaW5lIE1US19KUEVHX0ZNVF9GTEFHX0VOQ19PVVRQ VVQJQklUKDIpDQorI2RlZmluZSBNVEtfSlBFR19GTVRfRkxBR19FTkNfQ0FQVFVSRQlCSVQoMykN CiANCiAjZGVmaW5lIE1US19KUEVHX01JTl9XSURUSAkzMlUNCiAjZGVmaW5lIE1US19KUEVHX01J Tl9IRUlHSFQJMzJVDQotI2RlZmluZSBNVEtfSlBFR19NQVhfV0lEVEgJODE5MlUNCi0jZGVmaW5l IE1US19KUEVHX01BWF9IRUlHSFQJODE5MlUNCisjZGVmaW5lIE1US19KUEVHX01BWF9XSURUSAk2 NTUzNVUNCisjZGVmaW5lIE1US19KUEVHX01BWF9IRUlHSFQJNjU1MzVVDQogDQogI2RlZmluZSBN VEtfSlBFR19ERUZBVUxUX1NJWkVJTUFHRQkoMSAqIDEwMjQgKiAxMDI0KQ0KKyNkZWZpbmUgTVRL X0pQRUdfREVGQVVMVF9FWElGX1NJWkUJKDY0ICogMTAyNCkNCiANCiAvKioNCiAgKiBlbnVtIG10 a19qcGVnX2N0eF9zdGF0ZSAtIGNvbnRleCBzdGF0ZSBvZiBqcGVnDQpAQCAtMzksNiArNDIsMTgg QEAgZW51bSBtdGtfanBlZ19jdHhfc3RhdGUgew0KIAlNVEtfSlBFR19TT1VSQ0VfQ0hBTkdFLA0K IH07DQogDQorLyoqDQorICogbXRrX2pwZWdfdmFyaWFudCAtIG10ayBqcGVnIGRyaXZlciB2YXJp YW50DQorICogQGlzX2VuY29kZXI6CQlkcml2ZXIgbW9kZSBpcyBqcGVnIGVuY29kZXINCisgKiBA Y2xrX25hbWVzOgkJY2xvY2sgbmFtZXMNCisgKiBAbnVtX2Nsb2NrczoJCW51bWJlcnMgb2YgY2xv Y2sNCisgKi8NCitzdHJ1Y3QgbXRrX2pwZWdfdmFyaWFudCB7DQorCWJvb2wgaXNfZW5jb2RlcjsN CisJY29uc3QgY2hhcgkJKmNsa19uYW1lc1tNVEtfSlBFR19NQVhfQ0xPQ0tTXTsNCisJaW50CQkJ bnVtX2Nsb2NrczsNCit9Ow0KKw0KIC8qKg0KICAqIHN0cnVjdCBtdF9qcGVnIC0gSlBFRyBJUCBh YnN0cmFjdGlvbg0KICAqIEBsb2NrOgkJdGhlIG11dGV4IHByb3RlY3RpbmcgdGhpcyBzdHJ1Y3R1 cmUNCkBAIC00OCwxMSArNjMsMTEgQEAgZW51bSBtdGtfanBlZ19jdHhfc3RhdGUgew0KICAqIEB2 NGwyX2RldjoJCXY0bDIgZGV2aWNlIGZvciBtZW0ybWVtIG1vZGUNCiAgKiBAbTJtX2RldjoJCXY0 bDIgbWVtMm1lbSBkZXZpY2UgZGF0YQ0KICAqIEBhbGxvY19jdHg6CQl2aWRlb2J1ZjIgbWVtb3J5 IGFsbG9jYXRvcidzIGNvbnRleHQNCi0gKiBAZGVjX3ZkZXY6CQl2aWRlbyBkZXZpY2Ugbm9kZSBm b3IgZGVjb2RlciBtZW0ybWVtIG1vZGUNCi0gKiBAZGVjX3JlZ19iYXNlOglKUEVHIHJlZ2lzdGVy cyBtYXBwaW5nDQotICogQGNsa19qZGVjOgkJSlBFRyBodyB3b3JraW5nIGNsb2NrDQotICogQGNs a19qZGVjX3NtaToJSlBFRyBTTUkgYnVzIGNsb2NrDQorICogQHZkZXY6CQl2aWRlbyBkZXZpY2Ug bm9kZSBmb3IganBlZyBtZW0ybWVtIG1vZGUNCisgKiBAcmVnX2Jhc2U6CQlKUEVHIHJlZ2lzdGVy cyBtYXBwaW5nDQogICogQGxhcmI6CQlTTUkgZGV2aWNlDQorICogQGNsb2NrczoJCUpQRUcgSVAg Y2xvY2socykNCisgKiBAdmFyaWFudDoJCWRyaXZlciB2YXJpYW50IHRvIGJlIHVzZWQNCiAgKi8N CiBzdHJ1Y3QgbXRrX2pwZWdfZGV2IHsNCiAJc3RydWN0IG11dGV4CQlsb2NrOw0KQEAgLTYyLDE2 ICs3NywxNyBAQCBzdHJ1Y3QgbXRrX2pwZWdfZGV2IHsNCiAJc3RydWN0IHY0bDJfZGV2aWNlCXY0 bDJfZGV2Ow0KIAlzdHJ1Y3QgdjRsMl9tMm1fZGV2CSptMm1fZGV2Ow0KIAl2b2lkCQkJKmFsbG9j X2N0eDsNCi0Jc3RydWN0IHZpZGVvX2RldmljZQkqZGVjX3ZkZXY7DQotCXZvaWQgX19pb21lbQkJ KmRlY19yZWdfYmFzZTsNCi0Jc3RydWN0IGNsawkJKmNsa19qZGVjOw0KLQlzdHJ1Y3QgY2xrCQkq Y2xrX2pkZWNfc21pOw0KKwlzdHJ1Y3QgdmlkZW9fZGV2aWNlCSp2ZGV2Ow0KKwl2b2lkIF9faW9t ZW0JCSpyZWdfYmFzZTsNCiAJc3RydWN0IGRldmljZQkJKmxhcmI7DQorCXN0cnVjdCBjbGsJCSpj bG9ja3NbTVRLX0pQRUdfTUFYX0NMT0NLU107DQorCWNvbnN0IHN0cnVjdCBtdGtfanBlZ192YXJp YW50ICp2YXJpYW50Ow0KIH07DQogDQogLyoqDQogICogc3RydWN0IGpwZWdfZm10IC0gZHJpdmVy J3MgaW50ZXJuYWwgY29sb3IgZm9ybWF0IGRhdGENCiAgKiBAZm91cmNjOgl0aGUgZm91cmNjIGNv ZGUsIDAgaWYgbm90IGFwcGxpY2FibGUNCisgKiBAaHdfZm9ybWF0OgloYXJkd2FyZSBmb3JtYXQg dmFsdWUNCiAgKiBAaF9zYW1wbGU6CWhvcml6b250YWwgc2FtcGxlIGNvdW50IG9mIHBsYW5lIGlu IDQgKiA0IHBpeGVsIGltYWdlDQogICogQHZfc2FtcGxlOgl2ZXJ0aWNhbCBzYW1wbGUgY291bnQg b2YgcGxhbmUgaW4gNCAqIDQgcGl4ZWwgaW1hZ2UNCiAgKiBAY29scGxhbmVzOgludW1iZXIgb2Yg Y29sb3IgcGxhbmVzICgxIGZvciBwYWNrZWQgZm9ybWF0cykNCkBAIC04MSw2ICs5Nyw3IEBAIHN0 cnVjdCBtdGtfanBlZ19kZXYgew0KICAqLw0KIHN0cnVjdCBtdGtfanBlZ19mbXQgew0KIAl1MzIJ Zm91cmNjOw0KKwl1MzIJaHdfZm9ybWF0Ow0KIAlpbnQJaF9zYW1wbGVbVklERU9fTUFYX1BMQU5F U107DQogCWludAl2X3NhbXBsZVtWSURFT19NQVhfUExBTkVTXTsNCiAJaW50CWNvbHBsYW5lczsN CkBAIC0xMTMsNiArMTMwLDEwIEBAIHN0cnVjdCBtdGtfanBlZ19xX2RhdGEgew0KICAqIEBjYXBf cToJCWRlc3RpbmF0aW9uIChjYXB0dXJlKSBxdWV1ZSBxdWV1ZSBpbmZvcm1hdGlvbg0KICAqIEBm aDoJCQlWNEwyIGZpbGUgaGFuZGxlDQogICogQHN0YXRlOgkJc3RhdGUgb2YgdGhlIGNvbnRleHQN CisgKiBAZW5hYmxlX2V4aWY6CWVuYWJsZSBleGlmIG1vZGUgb2YganBlZyBlbmNvZGVyDQorICog QGVuY19xdWFsaXR5OglqcGVnIGVuY29kZXIgcXVhbGl0eQ0KKyAqIEByZXN0YXJ0X2ludGVydmFs OglqcGVnIGVuY29kZXIgcmVzdGFydCBpbnRlcnZhbA0KKyAqIEBjdHJsX2hkbDoJCWNvbnRyb2xz IGhhbmRsZXINCiAgKiBAY29sb3JzcGFjZTogZW51bSB2NGwyX2NvbG9yc3BhY2U7IHN1cHBsZW1l bnRhbCB0byBwaXhlbGZvcm1hdA0KICAqIEB5Y2Jjcl9lbmM6IGVudW0gdjRsMl95Y2Jjcl9lbmNv ZGluZywgWSdDYkNyIGVuY29kaW5nDQogICogQHF1YW50aXphdGlvbjogZW51bSB2NGwyX3F1YW50 aXphdGlvbiwgY29sb3JzcGFjZSBxdWFudGl6YXRpb24NCkBAIC0xMjQsNiArMTQ1LDEwIEBAIHN0 cnVjdCBtdGtfanBlZ19jdHggew0KIAlzdHJ1Y3QgbXRrX2pwZWdfcV9kYXRhCQljYXBfcTsNCiAJ c3RydWN0IHY0bDJfZmgJCQlmaDsNCiAJZW51bSBtdGtfanBlZ19jdHhfc3RhdGUJCXN0YXRlOw0K Kwlib29sCQkJCWVuYWJsZV9leGlmOw0KKwl1OAkJCQllbmNfcXVhbGl0eTsNCisJdTgJCQkJcmVz dGFydF9pbnRlcnZhbDsNCisJc3RydWN0IHY0bDJfY3RybF9oYW5kbGVyCWN0cmxfaGRsOw0KIA0K IAllbnVtIHY0bDJfY29sb3JzcGFjZSBjb2xvcnNwYWNlOw0KIAllbnVtIHY0bDJfeWNiY3JfZW5j b2RpbmcgeWNiY3JfZW5jOw0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRr LWpwZWcvbXRrX2pwZWdfZGVjX2h3LmggYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVn L210a19qcGVnX2RlY19ody5oDQppbmRleCAxY2MzN2RiZmM4ZTcuLmNlMjYzZGI1ZjMwYSAxMDA2 NDQNCi0tLSBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfZGVjX2h3 LmgNCisrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfZGVjX2h3 LmgNCkBAIC0zLDEwICszLDExIEBADQogICogQ29weXJpZ2h0IChjKSAyMDE2IE1lZGlhVGVrIElu Yy4NCiAgKiBBdXRob3I6IE1pbmcgSHNpdSBUc2FpIDxtaW5naHNpdS50c2FpQG1lZGlhdGVrLmNv bT4NCiAgKiAgICAgICAgIFJpY2sgQ2hhbmcgPHJpY2suY2hhbmdAbWVkaWF0ZWsuY29tPg0KKyAq ICAgICAgICAgWGlhIEppYW5nIDx4aWEuamlhbmdAbWVkaWF0ZWsuY29tPg0KICAqLw0KIA0KLSNp Zm5kZWYgX01US19KUEVHX0hXX0gNCi0jZGVmaW5lIF9NVEtfSlBFR19IV19IDQorI2lmbmRlZiBf TVRLX0pQRUdfREVDX0hXX0gNCisjZGVmaW5lIF9NVEtfSlBFR19ERUNfSFdfSA0KIA0KICNpbmNs dWRlIDxtZWRpYS92aWRlb2J1ZjItY29yZS5oPg0KIA0KQEAgLTc1LDQgKzc2LDQgQEAgdm9pZCBt dGtfanBlZ19kZWNfc2V0X2NvbmZpZyh2b2lkIF9faW9tZW0gKmJhc2UsDQogdm9pZCBtdGtfanBl Z19kZWNfcmVzZXQodm9pZCBfX2lvbWVtICpkZWNfcmVnX2Jhc2UpOw0KIHZvaWQgbXRrX2pwZWdf ZGVjX3N0YXJ0KHZvaWQgX19pb21lbSAqZGVjX3JlZ19iYXNlKTsNCiANCi0jZW5kaWYgLyogX01U S19KUEVHX0hXX0ggKi8NCisjZW5kaWYgLyogX01US19KUEVHX0RFQ19IV19IICovDQpkaWZmIC0t Z2l0IGEvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19lbmNfaHcuYyBi L2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfZW5jX2h3LmMNCm5ldyBm aWxlIG1vZGUgMTAwNjQ0DQppbmRleCAwMDAwMDAwMDAwMDAuLjdmYzFkZTkyMGE3NQ0KLS0tIC9k ZXYvbnVsbA0KKysrIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19l bmNfaHcuYw0KQEAgLTAsMCArMSwxOTMgQEANCisvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjog R1BMLTIuMC1vbmx5DQorLyoNCisgKiBDb3B5cmlnaHQgKGMpIDIwMTkgTWVkaWFUZWsgSW5jLg0K KyAqIEF1dGhvcjogWGlhIEppYW5nIDx4aWEuamlhbmdAbWVkaWF0ZWsuY29tPg0KKyAqDQorICov DQorDQorI2luY2x1ZGUgPGxpbnV4L2lvLmg+DQorI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPg0K KyNpbmNsdWRlIDxtZWRpYS92aWRlb2J1ZjItY29yZS5oPg0KKw0KKyNpbmNsdWRlICJtdGtfanBl Z19lbmNfaHcuaCINCisNCitzdGF0aWMgY29uc3Qgc3RydWN0IG10a19qcGVnX2VuY19xbHQgbXRr X2pwZWdfZW5jX3F1YWxpdHlbXSA9IHsNCisJey5xdWFsaXR5X3BhcmFtID0gMzQsIC5oYXJkd2Fy ZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTM0fSwNCisJey5xdWFsaXR5X3BhcmFtID0gMzks IC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTM5fSwNCisJey5xdWFsaXR5X3Bh cmFtID0gNDgsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTQ4fSwNCisJey5x dWFsaXR5X3BhcmFtID0gNjAsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTYw fSwNCisJey5xdWFsaXR5X3BhcmFtID0gNjQsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FV QUxJVFlfUTY0fSwNCisJey5xdWFsaXR5X3BhcmFtID0gNjgsIC5oYXJkd2FyZV92YWx1ZSA9IEpQ RUdfRU5DX1FVQUxJVFlfUTY4fSwNCisJey5xdWFsaXR5X3BhcmFtID0gNzQsIC5oYXJkd2FyZV92 YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTc0fSwNCisJey5xdWFsaXR5X3BhcmFtID0gODAsIC5o YXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTgwfSwNCisJey5xdWFsaXR5X3BhcmFt ID0gODIsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTgyfSwNCisJey5xdWFs aXR5X3BhcmFtID0gODQsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTg0fSwN CisJey5xdWFsaXR5X3BhcmFtID0gODcsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJ VFlfUTg3fSwNCisJey5xdWFsaXR5X3BhcmFtID0gOTAsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdf RU5DX1FVQUxJVFlfUTkwfSwNCisJey5xdWFsaXR5X3BhcmFtID0gOTIsIC5oYXJkd2FyZV92YWx1 ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTkyfSwNCisJey5xdWFsaXR5X3BhcmFtID0gOTUsIC5oYXJk d2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTk1fSwNCisJey5xdWFsaXR5X3BhcmFtID0g OTcsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTk3fSwNCit9Ow0KKw0KK3Zv aWQgbXRrX2pwZWdfZW5jX3Jlc2V0KHZvaWQgX19pb21lbSAqYmFzZSkNCit7DQorCXdyaXRlbCgw eDAwLCBiYXNlICsgSlBFR19FTkNfUlNUQik7DQorCXdyaXRlbChKUEVHX0VOQ19SRVNFVF9CSVQs IGJhc2UgKyBKUEVHX0VOQ19SU1RCKTsNCisJd3JpdGVsKDB4MDAsIGJhc2UgKyBKUEVHX0VOQ19D T0RFQ19TRUwpOw0KK30NCisNCit1MzIgbXRrX2pwZWdfZW5jX2dldF9hbmRfY2xlYXJfaW50X3N0 YXR1cyh2b2lkIF9faW9tZW0gKmJhc2UpDQorew0KKwl1MzIgcmV0Ow0KKw0KKwlyZXQgPSByZWFk bChiYXNlICsgSlBFR19FTkNfSU5UX1NUUykgJg0KKwkJICAgIEpQRUdfRU5DX0lOVF9TVEFUVVNf TUFTS19BTExJUlE7DQorCWlmIChyZXQpDQorCQl3cml0ZWwoMCwgYmFzZSArIEpQRUdfRU5DX0lO VF9TVFMpOw0KKw0KKwlyZXR1cm4gcmV0Ow0KK30NCisNCit1MzIgbXRrX2pwZWdfZW5jX2dldF9m aWxlX3NpemUodm9pZCBfX2lvbWVtICpiYXNlKQ0KK3sNCisJcmV0dXJuIHJlYWRsKGJhc2UgKyBK UEVHX0VOQ19ETUFfQUREUjApIC0NCisJICAgICAgIHJlYWRsKGJhc2UgKyBKUEVHX0VOQ19EU1Rf QUREUjApOw0KK30NCisNCit1MzIgbXRrX2pwZWdfZW5jX2VudW1fcmVzdWx0KHZvaWQgX19pb21l bSAqYmFzZSwgdTMyIGlycV9zdGF0dXMpDQorew0KKwlpZiAoaXJxX3N0YXR1cyAmIEpQRUdfRU5D X0lOVF9TVEFUVVNfRE9ORSkNCisJCXJldHVybiBNVEtfSlBFR19FTkNfUkVTVUxUX0RPTkU7DQor CWVsc2UgaWYgKGlycV9zdGF0dXMgJiBKUEVHX0VOQ19JTlRfU1RBVFVTX1NUQUxMKQ0KKwkJcmV0 dXJuIE1US19KUEVHX0VOQ19SRVNVTFRfU1RBTEw7DQorCWVsc2UNCisJCXJldHVybiBNVEtfSlBF R19FTkNfUkVTVUxUX1ZDT0RFQ19JUlE7DQorfQ0KKw0KK3ZvaWQgbXRrX2pwZWdfZW5jX3NldF9p bWdfc2l6ZSh2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiB3aWR0aCwgdTMyIGhlaWdodCkNCit7DQor CXUzMiB2YWx1ZTsNCisNCisJdmFsdWUgPSB3aWR0aCA8PCAxNiB8IGhlaWdodDsNCisJd3JpdGVs KHZhbHVlLCBiYXNlICsgSlBFR19FTkNfSU1HX1NJWkUpOw0KK30NCisNCit2b2lkIG10a19qcGVn X2VuY19zZXRfYmxrX251bSh2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBlbmNfZm9ybWF0LCB1MzIg d2lkdGgsDQorCQkJICAgICAgdTMyIGhlaWdodCkNCit7DQorCXUzMiBibGtfbnVtOw0KKwl1MzIg aXNfNDIwOw0KKwl1MzIgcGFkZGluZ193aWR0aDsNCisJdTMyIHBhZGRpbmdfaGVpZ2h0Ow0KKwl1 MzIgbHVtYV9ibG9ja3M7DQorCXUzMiBjaHJvbWFfYmxvY2tzOw0KKw0KKwlpc180MjAgPSAoZW5j X2Zvcm1hdCA9PSBWNEwyX1BJWF9GTVRfTlYxMk0gfHwNCisJCSAgZW5jX2Zvcm1hdCA9PSBWNEwy X1BJWF9GTVRfTlYyMU0pID8gMSA6IDA7DQorCXBhZGRpbmdfd2lkdGggPSByb3VuZF91cCh3aWR0 aCwgMTYpOw0KKwlwYWRkaW5nX2hlaWdodCA9IHJvdW5kX3VwKGhlaWdodCwgaXNfNDIwID8gMTYg OiA4KTsNCisNCisJbHVtYV9ibG9ja3MgPSBwYWRkaW5nX3dpZHRoIC8gOCAqIHBhZGRpbmdfaGVp Z2h0IC8gODsNCisJaWYgKGlzXzQyMCkNCisJCWNocm9tYV9ibG9ja3MgPSBsdW1hX2Jsb2NrcyAv IDQ7DQorCWVsc2UNCisJCWNocm9tYV9ibG9ja3MgPSBsdW1hX2Jsb2NrcyAvIDI7DQorDQorCWJs a19udW0gPSBsdW1hX2Jsb2NrcyArIDIgKiBjaHJvbWFfYmxvY2tzIC0gMTsNCisNCisJd3JpdGVs KGJsa19udW0sIGJhc2UgKyBKUEVHX0VOQ19CTEtfTlVNKTsNCit9DQorDQordm9pZCBtdGtfanBl Z19lbmNfc2V0X3N0cmlkZSh2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBlbmNfZm9ybWF0LCB1MzIg d2lkdGgsDQorCQkJICAgICB1MzIgaGVpZ2h0LCB1MzIgYnl0ZXNwZXJsaW5lKQ0KK3sNCisJdTMy IGltZ19zdHJpZGU7DQorCXUzMiBtZW1fc3RyaWRlOw0KKw0KKwlpZiAoZW5jX2Zvcm1hdCA9PSBW NEwyX1BJWF9GTVRfTlYxMk0gfHwNCisJICAgIGVuY19mb3JtYXQgPT0gVjRMMl9QSVhfRk1UX05W MjFNKSB7DQorCQlpbWdfc3RyaWRlID0gcm91bmRfdXAod2lkdGgsIDE2KTsNCisJCW1lbV9zdHJp ZGUgPSBieXRlc3BlcmxpbmU7DQorCX0gZWxzZSB7DQorCQlpbWdfc3RyaWRlID0gcm91bmRfdXAo d2lkdGggKiAyLCAzMik7DQorCQltZW1fc3RyaWRlID0gaW1nX3N0cmlkZTsNCisJfQ0KKw0KKwl3 cml0ZWwoaW1nX3N0cmlkZSwgYmFzZSArIEpQRUdfRU5DX0lNR19TVFJJREUpOw0KKwl3cml0ZWwo bWVtX3N0cmlkZSwgYmFzZSArIEpQRUdfRU5DX1NUUklERSk7DQorfQ0KKw0KK3ZvaWQgbXRrX2pw ZWdfZW5jX3NldF9zcmNfYWRkcih2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBzcmNfYWRkciwNCisJ CQkgICAgICAgdTMyIHBsYW5lX2luZGV4KQ0KK3sNCisJaWYgKCFwbGFuZV9pbmRleCkNCisJCXdy aXRlbChzcmNfYWRkciwgYmFzZSArIEpQRUdfRU5DX1NSQ19MVU1BX0FERFIpOw0KKwllbHNlDQor CQl3cml0ZWwoc3JjX2FkZHIsIGJhc2UgKyBKUEVHX0VOQ19TUkNfQ0hST01BX0FERFIpOw0KK30N CisNCit2b2lkIG10a19qcGVnX2VuY19zZXRfZHN0X2FkZHIodm9pZCBfX2lvbWVtICpiYXNlLCB1 MzIgZHN0X2FkZHIsDQorCQkJICAgICAgIHUzMiBzdGFsbF9zaXplLCB1MzIgaW5pdF9vZmZzZXQs DQorCQkJICAgICAgIHUzMiBvZmZzZXRfbWFzaykNCit7DQorCXdyaXRlbChpbml0X29mZnNldCAm IH4weGYsIGJhc2UgKyBKUEVHX0VOQ19PRkZTRVRfQUREUik7DQorCXdyaXRlbChvZmZzZXRfbWFz ayAmIDB4ZiwgYmFzZSArIEpQRUdfRU5DX0JZVEVfT0ZGU0VUX01BU0spOw0KKwl3cml0ZWwoZHN0 X2FkZHIgJiB+MHhmLCBiYXNlICsgSlBFR19FTkNfRFNUX0FERFIwKTsNCisJd3JpdGVsKChkc3Rf YWRkciArIHN0YWxsX3NpemUpICYgfjB4ZiwgYmFzZSArIEpQRUdfRU5DX1NUQUxMX0FERFIwKTsN Cit9DQorDQorc3RhdGljIHZvaWQgbXRrX2pwZWdfZW5jX3NldF9xdWFsaXR5KHZvaWQgX19pb21l bSAqYmFzZSwgdTMyIHF1YWxpdHkpDQorew0KKwl1MzIgdmFsdWU7DQorCXUzMiBpLCBlbmNfcXVh bGl0eTsNCisNCisJZW5jX3F1YWxpdHkgPSBtdGtfanBlZ19lbmNfcXVhbGl0eVswXS5oYXJkd2Fy ZV92YWx1ZTsNCisJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUobXRrX2pwZWdfZW5jX3F1YWxp dHkpOyBpKyspIHsNCisJCWlmIChxdWFsaXR5IDw9IG10a19qcGVnX2VuY19xdWFsaXR5W2ldLnF1 YWxpdHlfcGFyYW0pIHsNCisJCQllbmNfcXVhbGl0eSA9IG10a19qcGVnX2VuY19xdWFsaXR5W2ld LmhhcmR3YXJlX3ZhbHVlOw0KKwkJCWJyZWFrOw0KKwkJfQ0KKwl9DQorDQorCXZhbHVlID0gcmVh ZGwoYmFzZSArIEpQRUdfRU5DX1FVQUxJVFkpOw0KKwl2YWx1ZSA9ICh2YWx1ZSAmIEpQRUdfRU5D X1FVQUxJVFlfTUFTSykgfCBlbmNfcXVhbGl0eTsNCisJd3JpdGVsKHZhbHVlLCBiYXNlICsgSlBF R19FTkNfUVVBTElUWSk7DQorfQ0KKw0KK3N0YXRpYyB2b2lkIG10a19qcGVnX2VuY19zZXRfY3Ry bCh2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBlbmNfZm9ybWF0LA0KKwkJCQkgIGJvb2wgZXhpZl9l biwgdTMyIHJlc3RhcnRfaW50ZXJ2YWwpDQorew0KKwl1MzIgdmFsdWU7DQorDQorCXZhbHVlID0g cmVhZGwoYmFzZSArIEpQRUdfRU5DX0NUUkwpOw0KKwl2YWx1ZSAmPSB+SlBFR19FTkNfQ1RSTF9Z VVZfRk9STUFUX01BU0s7DQorCXZhbHVlIHw9IChlbmNfZm9ybWF0ICYgMykgPDwgMzsNCisJaWYg KGV4aWZfZW4pDQorCQl2YWx1ZSB8PSBKUEVHX0VOQ19DVFJMX0ZJTEVfRk9STUFUX0JJVDsNCisJ ZWxzZQ0KKwkJdmFsdWUgJj0gfkpQRUdfRU5DX0NUUkxfRklMRV9GT1JNQVRfQklUOw0KKwlpZiAo cmVzdGFydF9pbnRlcnZhbCkNCisJCXZhbHVlIHw9IEpQRUdfRU5DX0NUUkxfUkVTVEFSVF9FTl9C SVQ7DQorCWVsc2UNCisJCXZhbHVlICY9IH5KUEVHX0VOQ19DVFJMX1JFU1RBUlRfRU5fQklUOw0K Kwl3cml0ZWwodmFsdWUsIGJhc2UgKyBKUEVHX0VOQ19DVFJMKTsNCit9DQorDQordm9pZCBtdGtf anBlZ19lbmNfc2V0X2NvbmZpZyh2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBlbmNfZm9ybWF0LCBi b29sIGV4aWZfZW4sDQorCQkJICAgICB1MzIgcXVhbGl0eSwgdTMyIHJlc3RhcnRfaW50ZXJ2YWwp DQorew0KKwltdGtfanBlZ19lbmNfc2V0X3F1YWxpdHkoYmFzZSwgcXVhbGl0eSk7DQorDQorCW10 a19qcGVnX2VuY19zZXRfY3RybChiYXNlLCBlbmNfZm9ybWF0LCBleGlmX2VuLCByZXN0YXJ0X2lu dGVydmFsKTsNCisNCisJd3JpdGVsKHJlc3RhcnRfaW50ZXJ2YWwsIGJhc2UgKyBKUEVHX0VOQ19S U1RfTUNVX05VTSk7DQorfQ0KKw0KK3ZvaWQgbXRrX2pwZWdfZW5jX3N0YXJ0KHZvaWQgX19pb21l bSAqYmFzZSkNCit7DQorCXUzMiB2YWx1ZTsNCisNCisJdmFsdWUgPSByZWFkbChiYXNlICsgSlBF R19FTkNfQ1RSTCk7DQorCXZhbHVlIHw9IEpQRUdfRU5DX0NUUkxfSU5UX0VOX0JJVCB8IEpQRUdf RU5DX0NUUkxfRU5BQkxFX0JJVDsNCisJd3JpdGVsKHZhbHVlLCBiYXNlICsgSlBFR19FTkNfQ1RS TCk7DQorfQ0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRr X2pwZWdfZW5jX2h3LmggYi9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVn X2VuY19ody5oDQpuZXcgZmlsZSBtb2RlIDEwMDY0NA0KaW5kZXggMDAwMDAwMDAwMDAwLi43M2Zh ZjQ5YjY2N2MNCi0tLSAvZGV2L251bGwNCisrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRr LWpwZWcvbXRrX2pwZWdfZW5jX2h3LmgNCkBAIC0wLDAgKzEsMTIzIEBADQorLyogU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seSAqLw0KKy8qDQorICogQ29weXJpZ2h0IChjKSAy MDE5IE1lZGlhVGVrIEluYy4NCisgKiBBdXRob3I6IFhpYSBKaWFuZyA8eGlhLmppYW5nQG1lZGlh dGVrLmNvbT4NCisgKg0KKyAqLw0KKw0KKyNpZm5kZWYgX01US19KUEVHX0VOQ19IV19IDQorI2Rl ZmluZSBfTVRLX0pQRUdfRU5DX0hXX0gNCisNCisjaW5jbHVkZSA8bWVkaWEvdmlkZW9idWYyLWNv cmUuaD4NCisNCisjaW5jbHVkZSAibXRrX2pwZWdfY29yZS5oIg0KKw0KKyNkZWZpbmUgSlBFR19F TkNfSU5UX1NUQVRVU19ET05FCUJJVCgwKQ0KKyNkZWZpbmUgSlBFR19FTkNfSU5UX1NUQVRVU19T VEFMTAlCSVQoMSkNCisjZGVmaW5lIEpQRUdfRU5DX0lOVF9TVEFUVVNfVkNPREVDX0lSUQlCSVQo NCkNCisjZGVmaW5lIEpQRUdfRU5DX0lOVF9TVEFUVVNfTUFTS19BTExJUlEJMHgxMw0KKw0KKyNk ZWZpbmUgSlBFR19FTkNfRFNUX0FERFJfT0ZGU0VUX01BU0sJR0VOTUFTSygzLCAwKQ0KKyNkZWZp bmUgSlBFR19FTkNfUVVBTElUWV9NQVNLCQlHRU5NQVNLKDMxLCAxNikNCisNCisjZGVmaW5lIEpQ RUdfRU5DX0NUUkxfWVVWX0ZPUk1BVF9NQVNLCTB4MTgNCisjZGVmaW5lIEpQRUdfRU5DX0NUUkxf UkVTVEFSVF9FTl9CSVQJQklUKDEwKQ0KKyNkZWZpbmUgSlBFR19FTkNfQ1RSTF9GSUxFX0ZPUk1B VF9CSVQJQklUKDUpDQorI2RlZmluZSBKUEVHX0VOQ19DVFJMX0lOVF9FTl9CSVQJQklUKDIpDQor I2RlZmluZSBKUEVHX0VOQ19DVFJMX0VOQUJMRV9CSVQJQklUKDApDQorI2RlZmluZSBKUEVHX0VO Q19SRVNFVF9CSVQJCUJJVCgwKQ0KKw0KKyNkZWZpbmUgSlBFR19FTkNfWVVWX0ZPUk1BVF9ZVVlW CTANCisjZGVmaW5lIEpQRUdfRU5DX1lVVl9GT1JNQVRfWVZZVQkxDQorI2RlZmluZSBKUEVHX0VO Q19ZVVZfRk9STUFUX05WMTIJMg0KKyNkZWZpbmUgSkVQR19FTkNfWVVWX0ZPUk1BVF9OVjIxCTMN CisNCisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFlfUTYwCQkweDANCisjZGVmaW5lIEpQRUdfRU5D X1FVQUxJVFlfUTgwCQkweDENCisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFlfUTkwCQkweDINCisj ZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFlfUTk1CQkweDMNCisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJ VFlfUTM5CQkweDQNCisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFlfUTY4CQkweDUNCisjZGVmaW5l IEpQRUdfRU5DX1FVQUxJVFlfUTg0CQkweDYNCisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFlfUTky CQkweDcNCisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFlfUTQ4CQkweDgNCisjZGVmaW5lIEpQRUdf RU5DX1FVQUxJVFlfUTc0CQkweGENCisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFlfUTg3CQkweGIN CisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFlfUTM0CQkweGMNCisjZGVmaW5lIEpQRUdfRU5DX1FV QUxJVFlfUTY0CQkweGUNCisjZGVmaW5lIEpQRUdfRU5DX1FVQUxJVFlfUTgyCQkweGYNCisjZGVm aW5lIEpQRUdfRU5DX1FVQUxJVFlfUTk3CQkweDEwDQorDQorI2RlZmluZSBKUEVHX0VOQ19SU1RC CQkJMHgxMDANCisjZGVmaW5lIEpQRUdfRU5DX0NUUkwJCQkweDEwNA0KKyNkZWZpbmUgSlBFR19F TkNfUVVBTElUWQkJMHgxMDgNCisjZGVmaW5lIEpQRUdfRU5DX0JMS19OVU0JCTB4MTBDDQorI2Rl ZmluZSBKUEVHX0VOQ19CTEtfQ05UCQkweDExMA0KKyNkZWZpbmUgSlBFR19FTkNfSU5UX1NUUwkJ MHgxMWMNCisjZGVmaW5lIEpQRUdfRU5DX0RTVF9BRERSMAkJMHgxMjANCisjZGVmaW5lIEpQRUdf RU5DX0RNQV9BRERSMAkJMHgxMjQNCisjZGVmaW5lIEpQRUdfRU5DX1NUQUxMX0FERFIwCQkweDEy OA0KKyNkZWZpbmUgSlBFR19FTkNfT0ZGU0VUX0FERFIJCTB4MTM4DQorI2RlZmluZSBKUEVHX0VO Q19SU1RfTUNVX05VTQkJMHgxNTANCisjZGVmaW5lIEpQRUdfRU5DX0lNR19TSVpFCQkweDE1NA0K KyNkZWZpbmUgSlBFR19FTkNfREVCVUdfSU5GTzAJCTB4MTYwDQorI2RlZmluZSBKUEVHX0VOQ19E RUJVR19JTkZPMQkJMHgxNjQNCisjZGVmaW5lIEpQRUdfRU5DX1RPVEFMX0NZQ0xFCQkweDE2OA0K KyNkZWZpbmUgSlBFR19FTkNfQllURV9PRkZTRVRfTUFTSwkweDE2Yw0KKyNkZWZpbmUgSlBFR19F TkNfU1JDX0xVTUFfQUREUgkJMHgxNzANCisjZGVmaW5lIEpQRUdfRU5DX1NSQ19DSFJPTUFfQURE UgkweDE3NA0KKyNkZWZpbmUgSlBFR19FTkNfU1RSSURFCQkJMHgxNzgNCisjZGVmaW5lIEpQRUdf RU5DX0lNR19TVFJJREUJCTB4MTdjDQorI2RlZmluZSBKUEVHX0VOQ19EQ01fQ1RSTAkJMHgzMDAN CisjZGVmaW5lIEpQRUdfRU5DX0NPREVDX1NFTAkJMHgzMTQNCisjZGVmaW5lIEpQRUdfRU5DX1VM VFJBX1RIUkVTCQkweDMxOA0KKw0KK2VudW0gew0KKwlNVEtfSlBFR19FTkNfUkVTVUxUX0RPTkUs DQorCU1US19KUEVHX0VOQ19SRVNVTFRfU1RBTEwsDQorCU1US19KUEVHX0VOQ19SRVNVTFRfVkNP REVDX0lSUQ0KK307DQorDQorLyoqDQorICogc3RydWN0IG10a19qcGVnX2VuY19xbHQgLSBKUEVH IGVuY29kZXIgcXVhbGl0eSBkYXRhDQorICogQHF1YWxpdHlfcGFyYW06CXF1YWxpdHkgdmFsdWUN CisgKiBAaGFyZHdhcmVfdmFsdWU6CWhhcmR3YXJlIHZhbHVlIG9mIHF1YWxpdHkNCisgKi8NCitz dHJ1Y3QgbXRrX2pwZWdfZW5jX3FsdCB7DQorCXU4CXF1YWxpdHlfcGFyYW07DQorCXU4CWhhcmR3 YXJlX3ZhbHVlOw0KK307DQorDQorLyoqDQorICogc3RydWN0IG10X2pwZWdfZW5jX2JzIC0gSlBF RyBlbmNvZGVyIGJpdHN0cmVhbSAgYnVmZmVyDQorICogQGRtYV9hZGRyOgkJCUpQRUcgZW5jb2Rl ciBkZXN0aW5hdGlvbiBhZGRyZXNzDQorICogQHNpemU6CQkJSlBFRyBlbmNvZGVyIGJpc3RyZWFt IHNpemUNCisgKiBAZG1hX2FkZHJfb2Zmc2V0OgkJSlBFRyBlbmNvZGVyIG9mZnNldCBhZGRyZXNz DQorICogQGRtYV9hZGRyX29mZnNldG1hc2s6CUpQRUcgZW5jb2RlciBkZXN0aW5hdGlvbiBhZGRy ZXNzIG9mZnNldCBtYXNrDQorICovDQorc3RydWN0IG10a19qcGVnX2VuY19icyB7DQorCWRtYV9h ZGRyX3QJZG1hX2FkZHI7DQorCXNpemVfdAkJc2l6ZTsNCisJdTMyCQlkbWFfYWRkcl9vZmZzZXQ7 DQorCXUzMgkJZG1hX2FkZHJfb2Zmc2V0bWFzazsNCit9Ow0KKw0KK3ZvaWQgbXRrX2pwZWdfZW5j X3Jlc2V0KHZvaWQgX19pb21lbSAqYmFzZSk7DQordTMyIG10a19qcGVnX2VuY19nZXRfYW5kX2Ns ZWFyX2ludF9zdGF0dXModm9pZCBfX2lvbWVtICpiYXNlKTsNCit1MzIgbXRrX2pwZWdfZW5jX2dl dF9maWxlX3NpemUodm9pZCBfX2lvbWVtICpiYXNlKTsNCit1MzIgbXRrX2pwZWdfZW5jX2VudW1f cmVzdWx0KHZvaWQgX19pb21lbSAqYmFzZSwgdTMyIGlycV9zdGF0dXMpOw0KK3ZvaWQgbXRrX2pw ZWdfZW5jX3NldF9pbWdfc2l6ZSh2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiB3aWR0aCwgdTMyIGhl aWdodCk7DQordm9pZCBtdGtfanBlZ19lbmNfc2V0X2Jsa19udW0odm9pZCBfX2lvbWVtICpiYXNl LCB1MzIgZW5jX2Zvcm1hdCwgdTMyIHdpZHRoLA0KKwkJCSAgICAgIHUzMiBoZWlnaHQpOw0KK3Zv aWQgbXRrX2pwZWdfZW5jX3NldF9zdHJpZGUodm9pZCBfX2lvbWVtICpiYXNlLCB1MzIgZW5jX2Zv cm1hdCwgdTMyIHdpZHRoLA0KKwkJCSAgICAgdTMyIGhlaWdodCwgdTMyIGJ5dGVzcGVybGluZSk7 DQordm9pZCBtdGtfanBlZ19lbmNfc2V0X3NyY19hZGRyKHZvaWQgX19pb21lbSAqYmFzZSwgdTMy IHNyY19hZGRyLA0KKwkJCSAgICAgICB1MzIgcGxhbmVfaW5kZXgpOw0KK3ZvaWQgbXRrX2pwZWdf ZW5jX3NldF9kc3RfYWRkcih2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBkc3RfYWRkciwNCisJCQkg ICAgICAgdTMyIHN0YWxsX3NpemUsIHUzMiBpbml0X29mZnNldCwNCisJCQkgICAgICAgdTMyIG9m ZnNldF9tYXNrKTsNCit2b2lkIG10a19qcGVnX2VuY19zZXRfY29uZmlnKHZvaWQgX19pb21lbSAq YmFzZSwgdTMyIGVuY19mb3JtYXQsIGJvb2wgZXhpZl9lbiwNCisJCQkgICAgIHUzMiBxdWFsaXR5 LCB1MzIgcmVzdGFydF9pbnRlcnZhbCk7DQordm9pZCBtdGtfanBlZ19lbmNfc3RhcnQodm9pZCBf X2lvbWVtICplbmNfcmVnX2Jhc2UpOw0KKw0KKyNlbmRpZiAvKiBfTVRLX0pQRUdfRU5DX0hXX0gg Ki8NCi0tIA0KMi4xOC4wDQo= 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=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 D999CC43331 for ; Fri, 3 Apr 2020 09:52:30 +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 6B3F320737 for ; Fri, 3 Apr 2020 09:52: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="NAUbeUZh"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="Qg1IQzZo" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6B3F320737 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=oFxlSHGL/hIVP70ERyz50W89aQcZJC77FgD3FAawRSs=; b=NAUbeUZh+SJygO 6uDwrpx9/E0hfhGuYloX0OjQb4uEvNAx5nmtVxGzpfhWCPtcJXzTrckWnr0h2nJmtQA8rJj6Kl3O9 W+JD2imEsxyLeJ6aPctm3nLywg2SJAY7kgjKWNKP4bFvp95UCwBo2jVfu6Q5jkGU+gOBbnOzT41TG UTxx5OMDitNKWj8kFkpCGcp3KK/DLu8EWfAO+OFir29QV9f4lJpmyd1Kc8/FBPZVGsNlqMXz1RLTm MuvqpJq2YH1rOZtzPL8LEhauOFJR9Ff7iDsIEt0cra8O7x5dmNY0FmKjlbwmFmI/MNpkZB9/w/scT N4R/QEEf59CMNUjkZX4g==; 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 1jKIzp-0001kY-04; Fri, 03 Apr 2020 09:52:17 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jKIyK-0000Eq-6U; Fri, 03 Apr 2020 09:50:48 +0000 X-UUID: e95363bf782a42fc839da6a4e612753f-20200403 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=C5GZe5ZHxZEA0bVUU+2nNLCD3vP43u8gHp5y89FHgvQ=; b=Qg1IQzZoCMcLAyHprVvm48ysqdVbeMNN/OEf+4GoxyYCYYJJNS21Vk9k3eqwB11d9qcdcEPetwFhuChyMovmZ7d7suj9OtfIwMc6GC0Ljo2APWu5+8uX6Qs8i7GM9Oe+zgPXT33L4SOVbuobJA2BkQ11gpyy/WOz418svHp4Jtk=; X-UUID: e95363bf782a42fc839da6a4e612753f-20200403 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 786733852; Fri, 03 Apr 2020 01:50:33 -0800 Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Fri, 3 Apr 2020 02:40:51 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 3 Apr 2020 17:40:48 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 3 Apr 2020 17:40:47 +0800 From: Xia Jiang To: Hans Verkuil , Mauro Carvalho Chehab , Rob Herring , "Matthias Brugger" , Rick Chang Subject: [PATCH v8 14/14] media: platform: Add jpeg dec/enc feature Date: Fri, 3 Apr 2020 17:40:33 +0800 Message-ID: <20200403094033.8288-15-xia.jiang@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20200403094033.8288-1-xia.jiang@mediatek.com> References: <20200403094033.8288-1-xia.jiang@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200403_025044_271503_84F858DD X-CRM114-Status: GOOD ( 16.34 ) 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: maoguang.meng@mediatek.com, devicetree@vger.kernel.org, mojahsu@chromium.org, srv_heupstream@mediatek.com, linux-kernel@vger.kernel.org, Tomasz Figa , senozhatsky@chromium.org, sj.huang@mediatek.com, drinkcat@chromium.org, linux-mediatek@lists.infradead.org, Xia Jiang , linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Marek Szyprowski 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 Add mtk jpeg encode v4l2 driver based on jpeg decode, because that jpeg decode and encode have great similarities with function operation. Signed-off-by: Xia Jiang --- v8:jpeg encoder and decoder use separate callbacks instead of repeating the if/else in every callback. improve vidioc_try_fmt() implementation that can be shared by jpeg encoder and decoder. fix the bug of jpeg encoder s_selection implementation. cancel the state of the jpeg encoder. improve jpeg encoder and decoder set default params flow. put the clock names and other datas in a match_data struct. fix the bug of geting correctly quality value. do the all the bits' settings of one register in one function. move the code of mtk_jpeg_enc_reg.h to mtk_jpeg_enc_hw.h and delete mtk_jpeg_enc_reg.h. v7: reverse spin lock and unlock operation in device run function for multi-instance. v6: add space to arounding '+'. alignment 'struct mtk_jpeg_fmt *fmt' match open parenthesis. change 'mtk_jpeg_enc_set_encFormat' to 'mtk_jpeg_enc_set_enc_format'. make 'mtk_jpeg_ctrls_setup' to static prototype. delete unused variables 'jpeg'/'align_h'/'align_w'/'flags'. initialize 'yuv_format'/'enc_quality' variables. v5: support crop for encoder and compose for decoder in s_selection and g_selection function. use clamp() to replace mtk_jpeg_bound_align_image() and round_up() to replace mtk_jpeg_align(). delete jpeg_enc_param/mtk_jpeg_enc_param structure and mtk_jpeg_set_param(), program the registers directly based on the original V4L2 values. move macro definition about hw to mtk_jpeg_enc_reg.h. delete unnecessary V4L2 logs in driver. cancel spin lock and unlock operation in deviec run function. change jpeg enc register offset hex numberals from upercase to lowercase. v4: split mtk_jpeg_try_fmt_mplane() to two functions, one for encoder, one for decoder. split mtk_jpeg_set_default_params() to two functions, one for encoder, one for decoder. add cropping support for encoder in g/s_selection ioctls. change exif mode support by using V4L2_JPEG_ACTIVE_MARKER_APP1. change MTK_JPEG_MAX_WIDTH/MTK_JPEG_MAX_HEIGH from 8192 to 65535 by specification. move width shifting operation behind aligning operation in mtk_jpeg_try_enc_fmt_mplane() for bug fix. fix user abuseing data_offset issue for DMABUF in mtk_jpeg_set_enc_src(). fix kbuild warings: change MTK_JPEG_MIN_HEIGHT/MTK_JPEG_MAX_HEIGHT and MTK_JPEG_MIN_WIDTH/MTK_JPEG_MAX_WIDTH from 'int' type to 'unsigned int' type. fix msleadingly indented of 'else'. v3: delete Change-Id. only test once handler->error after the last v4l2_ctrl_new_std(). seperate changes of v4l2-ctrls.c and v4l2-controls.h to new patch. v2: fix compliance test fail, check created buffer size in driver. --- drivers/media/platform/mtk-jpeg/Makefile | 5 +- .../media/platform/mtk-jpeg/mtk_jpeg_core.c | 1038 +++++++++++++---- .../media/platform/mtk-jpeg/mtk_jpeg_core.h | 51 +- .../media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h | 7 +- .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c | 193 +++ .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h | 123 ++ 6 files changed, 1188 insertions(+), 229 deletions(-) create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h diff --git a/drivers/media/platform/mtk-jpeg/Makefile b/drivers/media/platform/mtk-jpeg/Makefile index 48516dcf96e6..76c33aad0f3f 100644 --- a/drivers/media/platform/mtk-jpeg/Makefile +++ b/drivers/media/platform/mtk-jpeg/Makefile @@ -1,3 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -mtk_jpeg-objs := mtk_jpeg_core.o mtk_jpeg_dec_hw.o mtk_jpeg_dec_parse.o +mtk_jpeg-objs := mtk_jpeg_core.o \ + mtk_jpeg_dec_hw.o \ + mtk_jpeg_dec_parse.o \ + mtk_jpeg_enc_hw.o obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk_jpeg.o diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index 77a95185584c..18a759ce2c46 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -3,6 +3,7 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ #include @@ -23,11 +24,60 @@ #include #include +#include "mtk_jpeg_enc_hw.h" #include "mtk_jpeg_dec_hw.h" #include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_parse.h" -static struct mtk_jpeg_fmt mtk_jpeg_formats[] = { +static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { + { + .fourcc = V4L2_PIX_FMT_JPEG, + .colplanes = 1, + .flags = MTK_JPEG_FMT_FLAG_ENC_CAPTURE, + }, + { + .fourcc = V4L2_PIX_FMT_NV12M, + .hw_format = JPEG_ENC_YUV_FORMAT_NV12, + .h_sample = {4, 4}, + .v_sample = {4, 2}, + .colplanes = 2, + .h_align = 4, + .v_align = 4, + .flags = MTK_JPEG_FMT_FLAG_ENC_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_NV21M, + .hw_format = JEPG_ENC_YUV_FORMAT_NV21, + .h_sample = {4, 4}, + .v_sample = {4, 2}, + .colplanes = 2, + .h_align = 4, + .v_align = 4, + .flags = MTK_JPEG_FMT_FLAG_ENC_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .hw_format = JPEG_ENC_YUV_FORMAT_YUYV, + .h_sample = {8}, + .v_sample = {4}, + .colplanes = 1, + .h_align = 5, + .v_align = 3, + .flags = MTK_JPEG_FMT_FLAG_ENC_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_YVYU, + .hw_format = JPEG_ENC_YUV_FORMAT_YVYU, + .h_sample = {8}, + .v_sample = {4}, + .colplanes = 1, + .h_align = 5, + .v_align = 3, + .flags = MTK_JPEG_FMT_FLAG_ENC_OUTPUT, + }, +}; + +static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { { .fourcc = V4L2_PIX_FMT_JPEG, .colplanes = 1, @@ -53,7 +103,8 @@ static struct mtk_jpeg_fmt mtk_jpeg_formats[] = { }, }; -#define MTK_JPEG_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_formats) +#define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats) +#define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats) enum { MTK_JPEG_BUF_FLAGS_INIT = 0, @@ -70,6 +121,11 @@ struct mtk_jpeg_src_buf { static int debug; module_param(debug, int, 0644); +static inline struct mtk_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl) +{ + return container_of(ctrl->handler, struct mtk_jpeg_ctx, ctrl_hdl); +} + static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh) { return container_of(fh, struct mtk_jpeg_ctx, fh); @@ -81,12 +137,25 @@ static inline struct mtk_jpeg_src_buf *mtk_jpeg_vb2_to_srcbuf( return container_of(to_vb2_v4l2_buffer(vb), struct mtk_jpeg_src_buf, b); } -static int mtk_jpeg_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) +static int mtk_jpeg_enc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct mtk_jpeg_dev *jpeg = video_drvdata(file); + + strscpy(cap->driver, MTK_JPEG_NAME, sizeof(cap->driver)); + strscpy(cap->card, MTK_JPEG_NAME " encoder", sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", + dev_name(jpeg->dev)); + + return 0; +} + +static int mtk_jpeg_dec_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) { struct mtk_jpeg_dev *jpeg = video_drvdata(file); - strscpy(cap->driver, MTK_JPEG_NAME " decoder", sizeof(cap->driver)); + strscpy(cap->driver, MTK_JPEG_NAME, sizeof(cap->driver)); strscpy(cap->card, MTK_JPEG_NAME " decoder", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(jpeg->dev)); @@ -94,6 +163,54 @@ static int mtk_jpeg_querycap(struct file *file, void *priv, return 0; } +static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); + + switch (ctrl->id) { + case V4L2_CID_JPEG_RESTART_INTERVAL: + ctx->restart_interval = ctrl->val; + break; + case V4L2_CID_JPEG_COMPRESSION_QUALITY: + ctx->enc_quality = ctrl->val; + break; + case V4L2_CID_JPEG_ACTIVE_MARKER: + ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1 ? + true : false; + break; + } + + return 0; +} + +static const struct v4l2_ctrl_ops mtk_jpeg_enc_ctrl_ops = { + .s_ctrl = vidioc_jpeg_enc_s_ctrl, +}; + +static int mtk_jpeg_enc_ctrls_setup(struct mtk_jpeg_ctx *ctx) +{ + const struct v4l2_ctrl_ops *ops = &mtk_jpeg_enc_ctrl_ops; + struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl; + + v4l2_ctrl_handler_init(handler, 3); + + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_RESTART_INTERVAL, 0, 100, + 1, 0); + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_COMPRESSION_QUALITY, 48, + 100, 1, 90); + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_ACTIVE_MARKER, 0, + V4L2_JPEG_ACTIVE_MARKER_APP1, 0, 0); + + if (handler->error) { + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); + return handler->error; + } + + v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); + + return 0; +} + static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n, struct v4l2_fmtdesc *f, u32 type) { @@ -115,117 +232,105 @@ static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n, return 0; } -static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) +static int mtk_jpeg_enc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) { - return mtk_jpeg_enum_fmt(mtk_jpeg_formats, MTK_JPEG_NUM_FORMATS, f, + return mtk_jpeg_enum_fmt(mtk_jpeg_enc_formats, + MTK_JPEG_ENC_NUM_FORMATS, f, + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); +} + +static int mtk_jpeg_dec_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return mtk_jpeg_enum_fmt(mtk_jpeg_dec_formats, + MTK_JPEG_DEC_NUM_FORMATS, f, MTK_JPEG_FMT_FLAG_DEC_CAPTURE); } -static int mtk_jpeg_enum_fmt_vid_out(struct file *file, void *priv, - struct v4l2_fmtdesc *f) +static int mtk_jpeg_enc_enum_fmt_vid_out(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return mtk_jpeg_enum_fmt(mtk_jpeg_enc_formats, + MTK_JPEG_ENC_NUM_FORMATS, f, + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); +} + +static int mtk_jpeg_dec_enum_fmt_vid_out(struct file *file, void *priv, + struct v4l2_fmtdesc *f) { - return mtk_jpeg_enum_fmt(mtk_jpeg_formats, MTK_JPEG_NUM_FORMATS, f, - MTK_JPEG_FMT_FLAG_DEC_OUTPUT); + return mtk_jpeg_enum_fmt(mtk_jpeg_dec_formats, MTK_JPEG_DEC_NUM_FORMATS, + f, MTK_JPEG_FMT_FLAG_DEC_OUTPUT); } -static struct mtk_jpeg_q_data *mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx, - enum v4l2_buf_type type) +static struct mtk_jpeg_q_data * +mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx, enum v4l2_buf_type type) { if (V4L2_TYPE_IS_OUTPUT(type)) return &ctx->out_q; return &ctx->cap_q; } -static struct mtk_jpeg_fmt *mtk_jpeg_find_format(struct mtk_jpeg_ctx *ctx, - u32 pixelformat, +static struct mtk_jpeg_fmt *mtk_jpeg_find_format(u32 pixelformat, unsigned int fmt_type) { - unsigned int k, fmt_flag; - - fmt_flag = (fmt_type == MTK_JPEG_FMT_TYPE_OUTPUT) ? - MTK_JPEG_FMT_FLAG_DEC_OUTPUT : - MTK_JPEG_FMT_FLAG_DEC_CAPTURE; + unsigned int k; + struct mtk_jpeg_fmt *fmt; - for (k = 0; k < MTK_JPEG_NUM_FORMATS; k++) { - struct mtk_jpeg_fmt *fmt = &mtk_jpeg_formats[k]; + for (k = 0; k < MTK_JPEG_ENC_NUM_FORMATS; k++) { + fmt = &mtk_jpeg_enc_formats[k]; - if (fmt->fourcc == pixelformat && fmt->flags & fmt_flag) + if (fmt->fourcc == pixelformat && fmt->flags & fmt_type) return fmt; } - return NULL; -} + for (k = 0; k < MTK_JPEG_DEC_NUM_FORMATS; k++) { + fmt = &mtk_jpeg_dec_formats[k]; -static void mtk_jpeg_adjust_fmt_mplane(struct mtk_jpeg_ctx *ctx, - struct v4l2_format *f) -{ - struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; - struct mtk_jpeg_q_data *q_data; - int i; - - q_data = mtk_jpeg_get_q_data(ctx, f->type); - - pix_mp->width = q_data->w; - pix_mp->height = q_data->h; - pix_mp->pixelformat = q_data->fmt->fourcc; - pix_mp->num_planes = q_data->fmt->colplanes; - - for (i = 0; i < pix_mp->num_planes; i++) { - pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i]; - pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i]; + if (fmt->fourcc == pixelformat && fmt->flags & fmt_type) + return fmt; } + + return NULL; } -static int mtk_jpeg_try_fmt_mplane(struct v4l2_format *f, - struct mtk_jpeg_fmt *fmt, - struct mtk_jpeg_ctx *ctx, int q_type) +static int vidioc_try_fmt(struct v4l2_format *f, struct mtk_jpeg_fmt *fmt) { struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; int i; - memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); pix_mp->field = V4L2_FIELD_NONE; - - if (ctx->state != MTK_JPEG_INIT) { - mtk_jpeg_adjust_fmt_mplane(ctx, f); - return 0; - } - pix_mp->num_planes = fmt->colplanes; pix_mp->pixelformat = fmt->fourcc; - if (q_type == MTK_JPEG_FMT_TYPE_OUTPUT) { - struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0]; - + if (fmt->fourcc == V4L2_PIX_FMT_JPEG) { pix_mp->height = clamp(pix_mp->height, MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT); pix_mp->width = clamp(pix_mp->width, MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); - - memset(pfmt->reserved, 0, sizeof(pfmt->reserved)); - pfmt->bytesperline = 0; - /* Source size must be aligned to 128 */ - pfmt->sizeimage = round_up(pfmt->sizeimage, 128); - if (pfmt->sizeimage == 0) - pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE; - return 0; + pix_mp->plane_fmt[0].bytesperline = 0; + pix_mp->plane_fmt[0].sizeimage = + round_up(pix_mp->plane_fmt[0].sizeimage, 128); + if (pix_mp->plane_fmt[0].sizeimage == 0) + pix_mp->plane_fmt[0].sizeimage = + MTK_JPEG_DEFAULT_SIZEIMAGE; + } else { + pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align), + MTK_JPEG_MIN_HEIGHT, + MTK_JPEG_MAX_HEIGHT); + pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align), + MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); + for (i = 0; i < pix_mp->num_planes; i++) { + struct v4l2_plane_pix_format *pfmt = + &pix_mp->plane_fmt[i]; + u32 stride = pix_mp->width * fmt->h_sample[i] / 4; + u32 h = pix_mp->height * fmt->v_sample[i] / 4; + + pfmt->bytesperline = stride; + pfmt->sizeimage = stride * h; + } } - /* type is MTK_JPEG_FMT_TYPE_CAPTURE */ - pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align), - MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT); - pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align), - MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); - - for (i = 0; i < fmt->colplanes; i++) { - struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i]; - u32 stride = pix_mp->width * fmt->h_sample[i] / 4; - u32 h = pix_mp->height * fmt->v_sample[i] / 4; - - pfmt->bytesperline = stride; - pfmt->sizeimage = stride * h; - } return 0; } @@ -280,14 +385,35 @@ static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv, return 0; } -static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv, - struct v4l2_format *f) +static int mtk_jpeg_enc_try_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + struct mtk_jpeg_fmt *fmt; + + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); + if (!fmt) + fmt = ctx->cap_q.fmt; + + v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n", + f->type, + (fmt->fourcc & 0xff), + (fmt->fourcc >> 8 & 0xff), + (fmt->fourcc >> 16 & 0xff), + (fmt->fourcc >> 24 & 0xff)); + + return vidioc_try_fmt(f, fmt); +} + +static int mtk_jpeg_dec_try_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) { struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); struct mtk_jpeg_fmt *fmt; - fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat, - MTK_JPEG_FMT_TYPE_CAPTURE); + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); if (!fmt) fmt = ctx->cap_q.fmt; @@ -298,17 +424,43 @@ static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv, (fmt->fourcc >> 16 & 0xff), (fmt->fourcc >> 24 & 0xff)); - return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_CAPTURE); + if (ctx->state != MTK_JPEG_INIT) { + mtk_jpeg_g_fmt_vid_mplane(file, priv, f); + return 0; + } + + return vidioc_try_fmt(f, fmt); +} + +static int mtk_jpeg_enc_try_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + struct mtk_jpeg_fmt *fmt; + + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); + if (!fmt) + fmt = ctx->out_q.fmt; + + v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n", + f->type, + (fmt->fourcc & 0xff), + (fmt->fourcc >> 8 & 0xff), + (fmt->fourcc >> 16 & 0xff), + (fmt->fourcc >> 24 & 0xff)); + + return vidioc_try_fmt(f, fmt); } -static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv, - struct v4l2_format *f) +static int mtk_jpeg_dec_try_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) { struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); struct mtk_jpeg_fmt *fmt; - fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat, - MTK_JPEG_FMT_TYPE_OUTPUT); + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); if (!fmt) fmt = ctx->out_q.fmt; @@ -319,17 +471,21 @@ static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv, (fmt->fourcc >> 16 & 0xff), (fmt->fourcc >> 24 & 0xff)); - return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_OUTPUT); + if (ctx->state != MTK_JPEG_INIT) { + mtk_jpeg_g_fmt_vid_mplane(file, priv, f); + return 0; + } + + return vidioc_try_fmt(f, fmt); } static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, - struct v4l2_format *f) + struct v4l2_format *f, unsigned int fmt_type) { struct vb2_queue *vq; struct mtk_jpeg_q_data *q_data = NULL; struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; struct mtk_jpeg_dev *jpeg = ctx->jpeg; - unsigned int f_type; int i; vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); @@ -343,10 +499,7 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, return -EBUSY; } - f_type = V4L2_TYPE_IS_OUTPUT(f->type) ? - MTK_JPEG_FMT_TYPE_OUTPUT : MTK_JPEG_FMT_TYPE_CAPTURE; - - q_data->fmt = mtk_jpeg_find_format(ctx, pix_mp->pixelformat, f_type); + q_data->fmt = mtk_jpeg_find_format(pix_mp->pixelformat, fmt_type); q_data->w = pix_mp->width; q_data->h = pix_mp->height; ctx->colorspace = pix_mp->colorspace; @@ -374,28 +527,56 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, return 0; } -static int mtk_jpeg_s_fmt_vid_out_mplane(struct file *file, void *priv, - struct v4l2_format *f) +static int mtk_jpeg_enc_s_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + int ret; + + ret = mtk_jpeg_enc_try_fmt_vid_out_mplane(file, priv, f); + if (ret) + return ret; + + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); +} + +static int mtk_jpeg_dec_s_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) { int ret; - ret = mtk_jpeg_try_fmt_vid_out_mplane(file, priv, f); + ret = mtk_jpeg_dec_try_fmt_vid_out_mplane(file, priv, f); if (ret) return ret; - return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f); + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); } -static int mtk_jpeg_s_fmt_vid_cap_mplane(struct file *file, void *priv, - struct v4l2_format *f) +static int mtk_jpeg_enc_s_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) { int ret; - ret = mtk_jpeg_try_fmt_vid_cap_mplane(file, priv, f); + ret = mtk_jpeg_enc_try_fmt_vid_cap_mplane(file, priv, f); if (ret) return ret; - return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f); + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); +} + +static int mtk_jpeg_dec_s_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + int ret; + + ret = mtk_jpeg_dec_try_fmt_vid_cap_mplane(file, priv, f); + if (ret) + return ret; + + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); } static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx) @@ -420,8 +601,31 @@ static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh, return v4l2_ctrl_subscribe_event(fh, sub); } -static int mtk_jpeg_g_selection(struct file *file, void *priv, - struct v4l2_selection *s) +static int mtk_jpeg_enc_g_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + s->r.width = ctx->out_q.w; + s->r.height = ctx->out_q.h; + s->r.left = 0; + s->r.top = 0; + break; + default: + return -EINVAL; + } + return 0; +} + +static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, + struct v4l2_selection *s) { struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); @@ -446,11 +650,34 @@ static int mtk_jpeg_g_selection(struct file *file, void *priv, default: return -EINVAL; } + return 0; } -static int mtk_jpeg_s_selection(struct file *file, void *priv, - struct v4l2_selection *s) +static int mtk_jpeg_enc_s_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + s->r.left = 0; + s->r.top = 0; + ctx->out_q.w = min(s->r.width, ctx->out_q.w); + ctx->out_q.h = min(s->r.height, ctx->out_q.h); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int mtk_jpeg_dec_s_selection(struct file *file, void *priv, + struct v4l2_selection *s) { struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); @@ -467,6 +694,7 @@ static int mtk_jpeg_s_selection(struct file *file, void *priv, default: return -EINVAL; } + return 0; } @@ -495,20 +723,47 @@ static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf); } -static const struct v4l2_ioctl_ops mtk_jpeg_ioctl_ops = { - .vidioc_querycap = mtk_jpeg_querycap, - .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap, - .vidioc_enum_fmt_vid_out = mtk_jpeg_enum_fmt_vid_out, - .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane, - .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane, +static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = { + .vidioc_querycap = mtk_jpeg_enc_querycap, + .vidioc_enum_fmt_vid_cap = mtk_jpeg_enc_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = mtk_jpeg_enc_enum_fmt_vid_out, + .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_enc_try_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_enc_try_fmt_vid_out_mplane, + .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane, + .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane, + .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_enc_s_fmt_vid_cap_mplane, + .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_enc_s_fmt_vid_out_mplane, + .vidioc_qbuf = mtk_jpeg_qbuf, + .vidioc_subscribe_event = mtk_jpeg_subscribe_event, + .vidioc_g_selection = mtk_jpeg_enc_g_selection, + .vidioc_s_selection = mtk_jpeg_enc_s_selection, + + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +static const struct v4l2_ioctl_ops mtk_jpeg_dec_ioctl_ops = { + .vidioc_querycap = mtk_jpeg_dec_querycap, + .vidioc_enum_fmt_vid_cap = mtk_jpeg_dec_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = mtk_jpeg_dec_enum_fmt_vid_out, + .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_dec_try_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_dec_try_fmt_vid_out_mplane, .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane, .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane, - .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane, - .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane, + .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_dec_s_fmt_vid_cap_mplane, + .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_dec_s_fmt_vid_out_mplane, .vidioc_qbuf = mtk_jpeg_qbuf, .vidioc_subscribe_event = mtk_jpeg_subscribe_event, - .vidioc_g_selection = mtk_jpeg_g_selection, - .vidioc_s_selection = mtk_jpeg_s_selection, + .vidioc_g_selection = mtk_jpeg_dec_g_selection, + .vidioc_s_selection = mtk_jpeg_dec_s_selection, .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, @@ -586,8 +841,9 @@ static bool mtk_jpeg_check_resolution_change(struct mtk_jpeg_ctx *ctx, } q_data = &ctx->cap_q; - if (q_data->fmt != mtk_jpeg_find_format(ctx, param->dst_fourcc, - MTK_JPEG_FMT_TYPE_CAPTURE)) { + if (q_data->fmt != + mtk_jpeg_find_format(param->dst_fourcc, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE)) { v4l2_dbg(1, debug, &jpeg->v4l2_dev, "format change\n"); return true; } @@ -608,9 +864,8 @@ static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx, q_data = &ctx->cap_q; q_data->w = param->dec_w; q_data->h = param->dec_h; - q_data->fmt = mtk_jpeg_find_format(ctx, - param->dst_fourcc, - MTK_JPEG_FMT_TYPE_CAPTURE); + q_data->fmt = mtk_jpeg_find_format(param->dst_fourcc, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); for (i = 0; i < q_data->fmt->colplanes; i++) { q_data->bytesperline[i] = param->mem_stride[i]; @@ -627,7 +882,18 @@ static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx, param->dec_w, param->dec_h); } -static void mtk_jpeg_buf_queue(struct vb2_buffer *vb) +static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb) +{ + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + + v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n", + vb->vb2_queue->type, vb->index, vb); + + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb)); +} + +static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct mtk_jpeg_dec_param *param; @@ -679,7 +945,16 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); } -static void mtk_jpeg_stop_streaming(struct vb2_queue *q) +static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q) +{ + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); + struct vb2_v4l2_buffer *vb; + + while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); +} + +static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); struct vb2_v4l2_buffer *vb; @@ -705,13 +980,22 @@ static void mtk_jpeg_stop_streaming(struct vb2_queue *q) v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); } -static const struct vb2_ops mtk_jpeg_qops = { +static const struct vb2_ops mtk_jpeg_dec_qops = { .queue_setup = mtk_jpeg_queue_setup, .buf_prepare = mtk_jpeg_buf_prepare, - .buf_queue = mtk_jpeg_buf_queue, + .buf_queue = mtk_jpeg_dec_buf_queue, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, - .stop_streaming = mtk_jpeg_stop_streaming, + .stop_streaming = mtk_jpeg_dec_stop_streaming, +}; + +static const struct vb2_ops mtk_jpeg_enc_qops = { + .queue_setup = mtk_jpeg_queue_setup, + .buf_prepare = mtk_jpeg_buf_prepare, + .buf_queue = mtk_jpeg_enc_buf_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .stop_streaming = mtk_jpeg_enc_stop_streaming, }; static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx, @@ -751,7 +1035,86 @@ static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx, return 0; } -static void mtk_jpeg_device_run(void *priv) +static void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *dst_buf, + struct mtk_jpeg_enc_bs *bs) +{ + bs->dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + bs->dma_addr_offset = ctx->enable_exif ? MTK_JPEG_DEFAULT_EXIF_SIZE : 0; + bs->dma_addr_offsetmask = bs->dma_addr & JPEG_ENC_DST_ADDR_OFFSET_MASK; + bs->size = vb2_plane_size(dst_buf, 0); + + mtk_jpeg_enc_set_dst_addr(base, bs->dma_addr, bs->size, + bs->dma_addr_offset, + bs->dma_addr_offsetmask); +} + +static void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *src_buf) +{ + int i; + dma_addr_t dma_addr; + + mtk_jpeg_enc_set_img_size(base, ctx->out_q.w, ctx->out_q.h); + mtk_jpeg_enc_set_blk_num(base, ctx->out_q.fmt->fourcc, ctx->out_q.w, + ctx->out_q.h); + mtk_jpeg_enc_set_stride(base, ctx->out_q.fmt->fourcc, ctx->out_q.w, + ctx->out_q.h, ctx->out_q.bytesperline[0]); + + for (i = 0; i < src_buf->num_planes; i++) { + dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, i) + + src_buf->planes[i].data_offset; + mtk_jpeg_enc_set_src_addr(base, dma_addr, i); + } +} + +static void mtk_jpeg_enc_device_run(void *priv) +{ + struct mtk_jpeg_ctx *ctx = priv; + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + unsigned long flags; + struct mtk_jpeg_src_buf *jpeg_src_buf; + struct mtk_jpeg_enc_bs enc_bs; + int i, ret; + + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); + + if (jpeg_src_buf->flags & MTK_JPEG_BUF_FLAGS_LAST_FRAME) { + for (i = 0; i < dst_buf->vb2_buf.num_planes; i++) + vb2_set_plane_payload(&dst_buf->vb2_buf, i, 0); + buf_state = VB2_BUF_STATE_DONE; + goto enc_end; + } + + ret = pm_runtime_get_sync(jpeg->dev); + if (ret < 0) + goto enc_end; + + spin_lock_irqsave(&jpeg->hw_lock, flags); + mtk_jpeg_enc_reset(jpeg->reg_base); + + mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf, &enc_bs); + mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf); + mtk_jpeg_enc_set_config(jpeg->reg_base, ctx->out_q.fmt->hw_format, + ctx->enable_exif, ctx->enc_quality, + ctx->restart_interval); + mtk_jpeg_enc_start(jpeg->reg_base); + spin_unlock_irqrestore(&jpeg->hw_lock, flags); + return; + +enc_end: + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); +} + +static void mtk_jpeg_dec_device_run(void *priv) { struct mtk_jpeg_ctx *ctx = priv; struct mtk_jpeg_dev *jpeg = ctx->jpeg; @@ -786,15 +1149,16 @@ static void mtk_jpeg_device_run(void *priv) goto dec_end; mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs); - if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb)) + if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, + &dst_buf->vb2_buf, &fb)) goto dec_end; spin_lock_irqsave(&jpeg->hw_lock, flags); - mtk_jpeg_dec_reset(jpeg->dec_reg_base); - mtk_jpeg_dec_set_config(jpeg->dec_reg_base, + mtk_jpeg_dec_reset(jpeg->reg_base); + mtk_jpeg_dec_set_config(jpeg->reg_base, &jpeg_src_buf->dec_param, &bs, &fb); - mtk_jpeg_dec_start(jpeg->dec_reg_base); + mtk_jpeg_dec_start(jpeg->reg_base); spin_unlock_irqrestore(&jpeg->hw_lock, flags); return; @@ -806,20 +1170,30 @@ static void mtk_jpeg_device_run(void *priv) v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); } -static int mtk_jpeg_job_ready(void *priv) +static int mtk_jpeg_enc_job_ready(void *priv) +{ + return 1; +} + +static int mtk_jpeg_dec_job_ready(void *priv) { struct mtk_jpeg_ctx *ctx = priv; return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0; } -static const struct v4l2_m2m_ops mtk_jpeg_m2m_ops = { - .device_run = mtk_jpeg_device_run, - .job_ready = mtk_jpeg_job_ready, +static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = { + .device_run = mtk_jpeg_enc_device_run, + .job_ready = mtk_jpeg_enc_job_ready, }; -static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, - struct vb2_queue *dst_vq) +static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = { + .device_run = mtk_jpeg_dec_device_run, + .job_ready = mtk_jpeg_dec_job_ready, +}; + +static int mtk_jpeg_dec_queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) { struct mtk_jpeg_ctx *ctx = priv; int ret; @@ -828,7 +1202,7 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->io_modes = VB2_DMABUF | VB2_MMAP; src_vq->drv_priv = ctx; src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf); - src_vq->ops = &mtk_jpeg_qops; + src_vq->ops = &mtk_jpeg_dec_qops; src_vq->mem_ops = &vb2_dma_contig_memops; src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; src_vq->lock = &ctx->jpeg->lock; @@ -841,7 +1215,7 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; dst_vq->drv_priv = ctx; dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); - dst_vq->ops = &mtk_jpeg_qops; + dst_vq->ops = &mtk_jpeg_dec_qops; dst_vq->mem_ops = &vb2_dma_contig_memops; dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; dst_vq->lock = &ctx->jpeg->lock; @@ -851,24 +1225,112 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, return ret; } -static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) +static int mtk_jpeg_enc_queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) { + struct mtk_jpeg_ctx *ctx = priv; int ret; + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + src_vq->io_modes = VB2_DMABUF | VB2_MMAP; + src_vq->drv_priv = ctx; + src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf); + src_vq->ops = &mtk_jpeg_enc_qops; + src_vq->mem_ops = &vb2_dma_contig_memops; + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &ctx->jpeg->lock; + src_vq->dev = ctx->jpeg->dev; + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; + dst_vq->drv_priv = ctx; + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->ops = &mtk_jpeg_enc_qops; + dst_vq->mem_ops = &vb2_dma_contig_memops; + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->lock = &ctx->jpeg->lock; + dst_vq->dev = ctx->jpeg->dev; + ret = vb2_queue_init(dst_vq); + + return ret; +} + +static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) +{ + int ret, i; + ret = mtk_smi_larb_get(jpeg->larb); if (ret) dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret); - clk_prepare_enable(jpeg->clk_jdec_smi); - clk_prepare_enable(jpeg->clk_jdec); + + for (i = 0; i < jpeg->variant->num_clocks; i++) { + ret = clk_prepare_enable(jpeg->clocks[i]); + if (ret) { + while (--i >= 0) + clk_disable_unprepare(jpeg->clocks[i]); + } + } } static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) { - clk_disable_unprepare(jpeg->clk_jdec); - clk_disable_unprepare(jpeg->clk_jdec_smi); + int i; + + for (i = jpeg->variant->num_clocks - 1; i >= 0; i--) + clk_disable_unprepare(jpeg->clocks[i]); mtk_smi_larb_put(jpeg->larb); } +static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv) +{ + struct mtk_jpeg_dev *jpeg = priv; + struct mtk_jpeg_ctx *ctx; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct mtk_jpeg_src_buf *jpeg_src_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + u32 enc_irq_ret; + u32 enc_ret, result_size; + + spin_lock(&jpeg->hw_lock); + + ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); + if (!ctx) { + v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); + return IRQ_HANDLED; + } + + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); + + enc_ret = mtk_jpeg_enc_get_and_clear_int_status(jpeg->reg_base); + enc_irq_ret = mtk_jpeg_enc_enum_result(jpeg->reg_base, enc_ret); + + if (enc_irq_ret >= MTK_JPEG_ENC_RESULT_STALL) + mtk_jpeg_enc_reset(jpeg->reg_base); + + if (enc_irq_ret != MTK_JPEG_ENC_RESULT_DONE) { + dev_err(jpeg->dev, "encode failed\n"); + goto enc_end; + } + + result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); + vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); + + buf_state = VB2_BUF_STATE_DONE; + +enc_end: + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + spin_unlock(&jpeg->hw_lock); + pm_runtime_put_sync(ctx->jpeg->dev); + return IRQ_HANDLED; +} + static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) { struct mtk_jpeg_dev *jpeg = priv; @@ -876,13 +1338,13 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) struct vb2_v4l2_buffer *src_buf, *dst_buf; struct mtk_jpeg_src_buf *jpeg_src_buf; enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; - u32 dec_irq_ret; + u32 dec_irq_ret; u32 dec_ret; int i; spin_lock(&jpeg->hw_lock); - dec_ret = mtk_jpeg_dec_get_int_status(jpeg->dec_reg_base); + dec_ret = mtk_jpeg_dec_get_int_status(jpeg->reg_base); dec_irq_ret = mtk_jpeg_dec_enum_result(dec_ret); ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); if (!ctx) { @@ -895,7 +1357,7 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW) - mtk_jpeg_dec_reset(jpeg->dec_reg_base); + mtk_jpeg_dec_reset(jpeg->reg_base); if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) { dev_err(jpeg->dev, "decode failed\n"); @@ -917,39 +1379,131 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) return IRQ_HANDLED; } -static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx) +static void mtk_jpeg_set_enc_default_params(struct mtk_jpeg_ctx *ctx) { struct mtk_jpeg_q_data *q = &ctx->out_q; - int i; + struct v4l2_pix_format_mplane *pix_mp; + + pix_mp = kmalloc(sizeof(*pix_mp), GFP_KERNEL); + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; ctx->colorspace = V4L2_COLORSPACE_JPEG, ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; ctx->quantization = V4L2_QUANTIZATION_DEFAULT; ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; - - q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG, - MTK_JPEG_FMT_TYPE_OUTPUT); - q->w = MTK_JPEG_MIN_WIDTH; - q->h = MTK_JPEG_MIN_HEIGHT; - q->bytesperline[0] = 0; - q->sizeimage[0] = MTK_JPEG_DEFAULT_SIZEIMAGE; + pix_mp->width = MTK_JPEG_MIN_WIDTH; + pix_mp->height = MTK_JPEG_MIN_HEIGHT; + + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_YUYV, + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, + fmt.pix_mp), q->fmt); + q->w = pix_mp->width; + q->h = pix_mp->height; + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; q = &ctx->cap_q; - q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_YUV420M, - MTK_JPEG_FMT_TYPE_CAPTURE); - q->w = MTK_JPEG_MIN_WIDTH; - q->h = MTK_JPEG_MIN_HEIGHT; + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_JPEG, + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); + pix_mp->width = MTK_JPEG_MIN_WIDTH; + pix_mp->height = MTK_JPEG_MIN_HEIGHT; + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, + fmt.pix_mp), q->fmt); + q->w = pix_mp->width; + q->h = pix_mp->height; + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; +} + +static void mtk_jpeg_set_dec_default_params(struct mtk_jpeg_ctx *ctx) +{ + struct mtk_jpeg_q_data *q = &ctx->out_q; + struct v4l2_pix_format_mplane *pix_mp; + int i; + + pix_mp = kmalloc(sizeof(*pix_mp), GFP_KERNEL); + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; + ctx->colorspace = V4L2_COLORSPACE_JPEG, + ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + ctx->quantization = V4L2_QUANTIZATION_DEFAULT; + ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; + pix_mp->width = MTK_JPEG_MIN_WIDTH; + pix_mp->height = MTK_JPEG_MIN_HEIGHT; + + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_JPEG, + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, + fmt.pix_mp), q->fmt); + q->w = pix_mp->width; + q->h = pix_mp->height; + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; + + q = &ctx->cap_q; + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_YUV420M, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); + pix_mp->width = MTK_JPEG_MIN_WIDTH; + pix_mp->height = MTK_JPEG_MIN_HEIGHT; + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, + fmt.pix_mp), q->fmt); + q->w = pix_mp->width; + q->h = pix_mp->height; for (i = 0; i < q->fmt->colplanes; i++) { - u32 stride = q->w * q->fmt->h_sample[i] / 4; - u32 h = q->h * q->fmt->v_sample[i] / 4; + q->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage; + q->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline; + } +} + +static int mtk_jpeg_enc_open(struct file *file) +{ + struct mtk_jpeg_dev *jpeg = video_drvdata(file); + struct video_device *vfd = video_devdata(file); + struct mtk_jpeg_ctx *ctx; + int ret = 0; - q->bytesperline[i] = stride; - q->sizeimage[i] = stride * h; + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + if (mutex_lock_interruptible(&jpeg->lock)) { + ret = -ERESTARTSYS; + goto free; + } + + v4l2_fh_init(&ctx->fh, vfd); + file->private_data = &ctx->fh; + v4l2_fh_add(&ctx->fh); + + ctx->jpeg = jpeg; + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, + mtk_jpeg_enc_queue_init); + if (IS_ERR(ctx->fh.m2m_ctx)) { + ret = PTR_ERR(ctx->fh.m2m_ctx); + goto error; } + + ret = mtk_jpeg_enc_ctrls_setup(ctx); + if (ret) { + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n"); + goto error; + } + mtk_jpeg_set_enc_default_params(ctx); + + mutex_unlock(&jpeg->lock); + return 0; + +error: + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + mutex_unlock(&jpeg->lock); +free: + kfree(ctx); + return ret; } -static int mtk_jpeg_open(struct file *file) +static int mtk_jpeg_dec_open(struct file *file) { struct mtk_jpeg_dev *jpeg = video_drvdata(file); struct video_device *vfd = video_devdata(file); @@ -971,13 +1525,20 @@ static int mtk_jpeg_open(struct file *file) ctx->jpeg = jpeg; ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, - mtk_jpeg_queue_init); + mtk_jpeg_dec_queue_init); if (IS_ERR(ctx->fh.m2m_ctx)) { ret = PTR_ERR(ctx->fh.m2m_ctx); goto error; } - mtk_jpeg_set_default_params(ctx); + v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0); + ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); + if (ret) { + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg dec controls\n"); + goto error; + } + mtk_jpeg_set_dec_default_params(ctx); + mutex_unlock(&jpeg->lock); return 0; @@ -997,6 +1558,7 @@ static int mtk_jpeg_release(struct file *file) mutex_lock(&jpeg->lock); v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); kfree(ctx); @@ -1004,9 +1566,18 @@ static int mtk_jpeg_release(struct file *file) return 0; } -static const struct v4l2_file_operations mtk_jpeg_fops = { +static const struct v4l2_file_operations mtk_jpeg_enc_fops = { .owner = THIS_MODULE, - .open = mtk_jpeg_open, + .open = mtk_jpeg_enc_open, + .release = mtk_jpeg_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static const struct v4l2_file_operations mtk_jpeg_dec_fops = { + .owner = THIS_MODULE, + .open = mtk_jpeg_dec_open, .release = mtk_jpeg_release, .poll = v4l2_m2m_fop_poll, .unlocked_ioctl = video_ioctl2, @@ -1017,6 +1588,7 @@ static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg) { struct device_node *node; struct platform_device *pdev; + int i; node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0); if (!node) @@ -1030,19 +1602,24 @@ static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg) jpeg->larb = &pdev->dev; - jpeg->clk_jdec = devm_clk_get(jpeg->dev, "jpgdec"); - if (IS_ERR(jpeg->clk_jdec)) - return PTR_ERR(jpeg->clk_jdec); + for (i = 0; i < jpeg->variant->num_clocks; i++) { + jpeg->clocks[i] = devm_clk_get(jpeg->dev, + jpeg->variant->clk_names[i]); + if (IS_ERR(jpeg->clocks[i])) { + dev_err(&pdev->dev, "failed to get clock: %s\n", + jpeg->variant->clk_names[i]); + return PTR_ERR(jpeg->clocks[i]); + } + } - jpeg->clk_jdec_smi = devm_clk_get(jpeg->dev, "jpgdec-smi"); - return PTR_ERR_OR_ZERO(jpeg->clk_jdec_smi); + return 0; } static int mtk_jpeg_probe(struct platform_device *pdev) { struct mtk_jpeg_dev *jpeg; struct resource *res; - int dec_irq; + int jpeg_irq; int ret; jpeg = devm_kzalloc(&pdev->dev, sizeof(*jpeg), GFP_KERNEL); @@ -1052,25 +1629,30 @@ static int mtk_jpeg_probe(struct platform_device *pdev) mutex_init(&jpeg->lock); spin_lock_init(&jpeg->hw_lock); jpeg->dev = &pdev->dev; + jpeg->variant = of_device_get_match_data(jpeg->dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - jpeg->dec_reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(jpeg->dec_reg_base)) { - ret = PTR_ERR(jpeg->dec_reg_base); + jpeg->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(jpeg->reg_base)) { + ret = PTR_ERR(jpeg->reg_base); return ret; } - dec_irq = platform_get_irq(pdev, 0); - if (dec_irq < 0) { - dev_err(&pdev->dev, "Failed to get dec_irq %d.\n", dec_irq); - return dec_irq; + jpeg_irq = platform_get_irq(pdev, 0); + if (jpeg_irq < 0) { + dev_err(&pdev->dev, "Failed to get jpeg_irq %d.\n", jpeg_irq); + return jpeg_irq; } - ret = devm_request_irq(&pdev->dev, dec_irq, mtk_jpeg_dec_irq, 0, - pdev->name, jpeg); + if (jpeg->variant->is_encoder) + ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_enc_irq, + 0, pdev->name, jpeg); + else + ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_dec_irq, + 0, pdev->name, jpeg); if (ret) { - dev_err(&pdev->dev, "Failed to request dec_irq %d (%d)\n", - dec_irq, ret); + dev_err(&pdev->dev, "Failed to request jpeg_irq %d (%d)\n", + jpeg_irq, ret); goto err_req_irq; } @@ -1087,40 +1669,50 @@ static int mtk_jpeg_probe(struct platform_device *pdev) goto err_dev_register; } - jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_m2m_ops); + if (jpeg->variant->is_encoder) + jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_enc_m2m_ops); + else + jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_dec_m2m_ops); if (IS_ERR(jpeg->m2m_dev)) { v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n"); ret = PTR_ERR(jpeg->m2m_dev); goto err_m2m_init; } - jpeg->dec_vdev = video_device_alloc(); - if (!jpeg->dec_vdev) { + jpeg->vdev = video_device_alloc(); + if (!jpeg->vdev) { ret = -ENOMEM; - goto err_dec_vdev_alloc; + goto err_vfd_jpeg_alloc; } - snprintf(jpeg->dec_vdev->name, sizeof(jpeg->dec_vdev->name), - "%s-dec", MTK_JPEG_NAME); - jpeg->dec_vdev->fops = &mtk_jpeg_fops; - jpeg->dec_vdev->ioctl_ops = &mtk_jpeg_ioctl_ops; - jpeg->dec_vdev->minor = -1; - jpeg->dec_vdev->release = video_device_release; - jpeg->dec_vdev->lock = &jpeg->lock; - jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev; - jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M; - jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING | + snprintf(jpeg->vdev->name, sizeof(jpeg->vdev->name), + "%s-%s", MTK_JPEG_NAME, + jpeg->variant->is_encoder ? "enc" : "dec"); + if (jpeg->variant->is_encoder) { + jpeg->vdev->fops = &mtk_jpeg_enc_fops; + jpeg->vdev->ioctl_ops = &mtk_jpeg_enc_ioctl_ops; + } else { + jpeg->vdev->fops = &mtk_jpeg_dec_fops; + jpeg->vdev->ioctl_ops = &mtk_jpeg_dec_ioctl_ops; + } + jpeg->vdev->minor = -1; + jpeg->vdev->release = video_device_release; + jpeg->vdev->lock = &jpeg->lock; + jpeg->vdev->v4l2_dev = &jpeg->v4l2_dev; + jpeg->vdev->vfl_dir = VFL_DIR_M2M; + jpeg->vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; - ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_GRABBER, -1); + ret = video_register_device(jpeg->vdev, VFL_TYPE_GRABBER, -1); if (ret) { v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n"); - goto err_dec_vdev_register; + goto err_vfd_jpeg_register; } - video_set_drvdata(jpeg->dec_vdev, jpeg); + video_set_drvdata(jpeg->vdev, jpeg); v4l2_info(&jpeg->v4l2_dev, - "decoder device registered as /dev/video%d (%d,%d)\n", - jpeg->dec_vdev->num, VIDEO_MAJOR, jpeg->dec_vdev->minor); + "jpeg %s device registered as /dev/video%d (%d,%d)\n", + jpeg->variant->is_encoder ? "enc" : "dec", jpeg->vdev->num, + VIDEO_MAJOR, jpeg->vdev->minor); platform_set_drvdata(pdev, jpeg); @@ -1128,10 +1720,10 @@ static int mtk_jpeg_probe(struct platform_device *pdev) return 0; -err_dec_vdev_register: - video_device_release(jpeg->dec_vdev); +err_vfd_jpeg_register: + video_device_release(jpeg->vdev); -err_dec_vdev_alloc: +err_vfd_jpeg_alloc: v4l2_m2m_release(jpeg->m2m_dev); err_m2m_init: @@ -1151,8 +1743,8 @@ static int mtk_jpeg_remove(struct platform_device *pdev) struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); - video_unregister_device(jpeg->dec_vdev); - video_device_release(jpeg->dec_vdev); + video_unregister_device(jpeg->vdev); + video_device_release(jpeg->vdev); v4l2_m2m_release(jpeg->m2m_dev); v4l2_device_unregister(&jpeg->v4l2_dev); @@ -1211,14 +1803,36 @@ static const struct dev_pm_ops mtk_jpeg_pm_ops = { SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL) }; +static struct mtk_jpeg_variant mt8173_jpeg_drvdata = { + .is_encoder = false, + .clk_names = {"jpgdec-smi", "jpgdec"}, + .num_clocks = 2, +}; + +static struct mtk_jpeg_variant mt2701_jpeg_drvdata = { + .is_encoder = false, + .clk_names = {"jpgdec-smi", "jpgdec"}, + .num_clocks = 2, +}; + +static struct mtk_jpeg_variant mtk_jpeg_drvdata = { + .is_encoder = true, + .clk_names = {"jpgenc"}, + .num_clocks = 1, +}; + static const struct of_device_id mtk_jpeg_match[] = { { .compatible = "mediatek,mt8173-jpgdec", - .data = NULL, + .data = &mt8173_jpeg_drvdata, }, { .compatible = "mediatek,mt2701-jpgdec", - .data = NULL, + .data = &mt2701_jpeg_drvdata, + }, + { + .compatible = "mediatek,mtk-jpgenc", + .data = &mtk_jpeg_drvdata, }, {}, }; diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h index 9bbd615b1067..8f80f2a69d45 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h @@ -3,6 +3,7 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ #ifndef _MTK_JPEG_CORE_H @@ -16,19 +17,21 @@ #define MTK_JPEG_NAME "mtk-jpeg" #define MTK_JPEG_COMP_MAX 3 +#define MTK_JPEG_MAX_CLOCKS 2 + #define MTK_JPEG_FMT_FLAG_DEC_OUTPUT BIT(0) #define MTK_JPEG_FMT_FLAG_DEC_CAPTURE BIT(1) - -#define MTK_JPEG_FMT_TYPE_OUTPUT 1 -#define MTK_JPEG_FMT_TYPE_CAPTURE 2 +#define MTK_JPEG_FMT_FLAG_ENC_OUTPUT BIT(2) +#define MTK_JPEG_FMT_FLAG_ENC_CAPTURE BIT(3) #define MTK_JPEG_MIN_WIDTH 32U #define MTK_JPEG_MIN_HEIGHT 32U -#define MTK_JPEG_MAX_WIDTH 8192U -#define MTK_JPEG_MAX_HEIGHT 8192U +#define MTK_JPEG_MAX_WIDTH 65535U +#define MTK_JPEG_MAX_HEIGHT 65535U #define MTK_JPEG_DEFAULT_SIZEIMAGE (1 * 1024 * 1024) +#define MTK_JPEG_DEFAULT_EXIF_SIZE (64 * 1024) /** * enum mtk_jpeg_ctx_state - contex state of jpeg @@ -39,6 +42,18 @@ enum mtk_jpeg_ctx_state { MTK_JPEG_SOURCE_CHANGE, }; +/** + * mtk_jpeg_variant - mtk jpeg driver variant + * @is_encoder: driver mode is jpeg encoder + * @clk_names: clock names + * @num_clocks: numbers of clock + */ +struct mtk_jpeg_variant { + bool is_encoder; + const char *clk_names[MTK_JPEG_MAX_CLOCKS]; + int num_clocks; +}; + /** * struct mt_jpeg - JPEG IP abstraction * @lock: the mutex protecting this structure @@ -48,11 +63,11 @@ enum mtk_jpeg_ctx_state { * @v4l2_dev: v4l2 device for mem2mem mode * @m2m_dev: v4l2 mem2mem device data * @alloc_ctx: videobuf2 memory allocator's context - * @dec_vdev: video device node for decoder mem2mem mode - * @dec_reg_base: JPEG registers mapping - * @clk_jdec: JPEG hw working clock - * @clk_jdec_smi: JPEG SMI bus clock + * @vdev: video device node for jpeg mem2mem mode + * @reg_base: JPEG registers mapping * @larb: SMI device + * @clocks: JPEG IP clock(s) + * @variant: driver variant to be used */ struct mtk_jpeg_dev { struct mutex lock; @@ -62,16 +77,17 @@ struct mtk_jpeg_dev { struct v4l2_device v4l2_dev; struct v4l2_m2m_dev *m2m_dev; void *alloc_ctx; - struct video_device *dec_vdev; - void __iomem *dec_reg_base; - struct clk *clk_jdec; - struct clk *clk_jdec_smi; + struct video_device *vdev; + void __iomem *reg_base; struct device *larb; + struct clk *clocks[MTK_JPEG_MAX_CLOCKS]; + const struct mtk_jpeg_variant *variant; }; /** * struct jpeg_fmt - driver's internal color format data * @fourcc: the fourcc code, 0 if not applicable + * @hw_format: hardware format value * @h_sample: horizontal sample count of plane in 4 * 4 pixel image * @v_sample: vertical sample count of plane in 4 * 4 pixel image * @colplanes: number of color planes (1 for packed formats) @@ -81,6 +97,7 @@ struct mtk_jpeg_dev { */ struct mtk_jpeg_fmt { u32 fourcc; + u32 hw_format; int h_sample[VIDEO_MAX_PLANES]; int v_sample[VIDEO_MAX_PLANES]; int colplanes; @@ -113,6 +130,10 @@ struct mtk_jpeg_q_data { * @cap_q: destination (capture) queue queue information * @fh: V4L2 file handle * @state: state of the context + * @enable_exif: enable exif mode of jpeg encoder + * @enc_quality: jpeg encoder quality + * @restart_interval: jpeg encoder restart interval + * @ctrl_hdl: controls handler * @colorspace: enum v4l2_colorspace; supplemental to pixelformat * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding * @quantization: enum v4l2_quantization, colorspace quantization @@ -124,6 +145,10 @@ struct mtk_jpeg_ctx { struct mtk_jpeg_q_data cap_q; struct v4l2_fh fh; enum mtk_jpeg_ctx_state state; + bool enable_exif; + u8 enc_quality; + u8 restart_interval; + struct v4l2_ctrl_handler ctrl_hdl; enum v4l2_colorspace colorspace; enum v4l2_ycbcr_encoding ycbcr_enc; diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h index 1cc37dbfc8e7..ce263db5f30a 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h @@ -3,10 +3,11 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ -#ifndef _MTK_JPEG_HW_H -#define _MTK_JPEG_HW_H +#ifndef _MTK_JPEG_DEC_HW_H +#define _MTK_JPEG_DEC_HW_H #include @@ -75,4 +76,4 @@ void mtk_jpeg_dec_set_config(void __iomem *base, void mtk_jpeg_dec_reset(void __iomem *dec_reg_base); void mtk_jpeg_dec_start(void __iomem *dec_reg_base); -#endif /* _MTK_JPEG_HW_H */ +#endif /* _MTK_JPEG_DEC_HW_H */ diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c new file mode 100644 index 000000000000..7fc1de920a75 --- /dev/null +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Xia Jiang + * + */ + +#include +#include +#include + +#include "mtk_jpeg_enc_hw.h" + +static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { + {.quality_param = 34, .hardware_value = JPEG_ENC_QUALITY_Q34}, + {.quality_param = 39, .hardware_value = JPEG_ENC_QUALITY_Q39}, + {.quality_param = 48, .hardware_value = JPEG_ENC_QUALITY_Q48}, + {.quality_param = 60, .hardware_value = JPEG_ENC_QUALITY_Q60}, + {.quality_param = 64, .hardware_value = JPEG_ENC_QUALITY_Q64}, + {.quality_param = 68, .hardware_value = JPEG_ENC_QUALITY_Q68}, + {.quality_param = 74, .hardware_value = JPEG_ENC_QUALITY_Q74}, + {.quality_param = 80, .hardware_value = JPEG_ENC_QUALITY_Q80}, + {.quality_param = 82, .hardware_value = JPEG_ENC_QUALITY_Q82}, + {.quality_param = 84, .hardware_value = JPEG_ENC_QUALITY_Q84}, + {.quality_param = 87, .hardware_value = JPEG_ENC_QUALITY_Q87}, + {.quality_param = 90, .hardware_value = JPEG_ENC_QUALITY_Q90}, + {.quality_param = 92, .hardware_value = JPEG_ENC_QUALITY_Q92}, + {.quality_param = 95, .hardware_value = JPEG_ENC_QUALITY_Q95}, + {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, +}; + +void mtk_jpeg_enc_reset(void __iomem *base) +{ + writel(0x00, base + JPEG_ENC_RSTB); + writel(JPEG_ENC_RESET_BIT, base + JPEG_ENC_RSTB); + writel(0x00, base + JPEG_ENC_CODEC_SEL); +} + +u32 mtk_jpeg_enc_get_and_clear_int_status(void __iomem *base) +{ + u32 ret; + + ret = readl(base + JPEG_ENC_INT_STS) & + JPEG_ENC_INT_STATUS_MASK_ALLIRQ; + if (ret) + writel(0, base + JPEG_ENC_INT_STS); + + return ret; +} + +u32 mtk_jpeg_enc_get_file_size(void __iomem *base) +{ + return readl(base + JPEG_ENC_DMA_ADDR0) - + readl(base + JPEG_ENC_DST_ADDR0); +} + +u32 mtk_jpeg_enc_enum_result(void __iomem *base, u32 irq_status) +{ + if (irq_status & JPEG_ENC_INT_STATUS_DONE) + return MTK_JPEG_ENC_RESULT_DONE; + else if (irq_status & JPEG_ENC_INT_STATUS_STALL) + return MTK_JPEG_ENC_RESULT_STALL; + else + return MTK_JPEG_ENC_RESULT_VCODEC_IRQ; +} + +void mtk_jpeg_enc_set_img_size(void __iomem *base, u32 width, u32 height) +{ + u32 value; + + value = width << 16 | height; + writel(value, base + JPEG_ENC_IMG_SIZE); +} + +void mtk_jpeg_enc_set_blk_num(void __iomem *base, u32 enc_format, u32 width, + u32 height) +{ + u32 blk_num; + u32 is_420; + u32 padding_width; + u32 padding_height; + u32 luma_blocks; + u32 chroma_blocks; + + is_420 = (enc_format == V4L2_PIX_FMT_NV12M || + enc_format == V4L2_PIX_FMT_NV21M) ? 1 : 0; + padding_width = round_up(width, 16); + padding_height = round_up(height, is_420 ? 16 : 8); + + luma_blocks = padding_width / 8 * padding_height / 8; + if (is_420) + chroma_blocks = luma_blocks / 4; + else + chroma_blocks = luma_blocks / 2; + + blk_num = luma_blocks + 2 * chroma_blocks - 1; + + writel(blk_num, base + JPEG_ENC_BLK_NUM); +} + +void mtk_jpeg_enc_set_stride(void __iomem *base, u32 enc_format, u32 width, + u32 height, u32 bytesperline) +{ + u32 img_stride; + u32 mem_stride; + + if (enc_format == V4L2_PIX_FMT_NV12M || + enc_format == V4L2_PIX_FMT_NV21M) { + img_stride = round_up(width, 16); + mem_stride = bytesperline; + } else { + img_stride = round_up(width * 2, 32); + mem_stride = img_stride; + } + + writel(img_stride, base + JPEG_ENC_IMG_STRIDE); + writel(mem_stride, base + JPEG_ENC_STRIDE); +} + +void mtk_jpeg_enc_set_src_addr(void __iomem *base, u32 src_addr, + u32 plane_index) +{ + if (!plane_index) + writel(src_addr, base + JPEG_ENC_SRC_LUMA_ADDR); + else + writel(src_addr, base + JPEG_ENC_SRC_CHROMA_ADDR); +} + +void mtk_jpeg_enc_set_dst_addr(void __iomem *base, u32 dst_addr, + u32 stall_size, u32 init_offset, + u32 offset_mask) +{ + writel(init_offset & ~0xf, base + JPEG_ENC_OFFSET_ADDR); + writel(offset_mask & 0xf, base + JPEG_ENC_BYTE_OFFSET_MASK); + writel(dst_addr & ~0xf, base + JPEG_ENC_DST_ADDR0); + writel((dst_addr + stall_size) & ~0xf, base + JPEG_ENC_STALL_ADDR0); +} + +static void mtk_jpeg_enc_set_quality(void __iomem *base, u32 quality) +{ + u32 value; + u32 i, enc_quality; + + enc_quality = mtk_jpeg_enc_quality[0].hardware_value; + for (i = 0; i < ARRAY_SIZE(mtk_jpeg_enc_quality); i++) { + if (quality <= mtk_jpeg_enc_quality[i].quality_param) { + enc_quality = mtk_jpeg_enc_quality[i].hardware_value; + break; + } + } + + value = readl(base + JPEG_ENC_QUALITY); + value = (value & JPEG_ENC_QUALITY_MASK) | enc_quality; + writel(value, base + JPEG_ENC_QUALITY); +} + +static void mtk_jpeg_enc_set_ctrl(void __iomem *base, u32 enc_format, + bool exif_en, u32 restart_interval) +{ + u32 value; + + value = readl(base + JPEG_ENC_CTRL); + value &= ~JPEG_ENC_CTRL_YUV_FORMAT_MASK; + value |= (enc_format & 3) << 3; + if (exif_en) + value |= JPEG_ENC_CTRL_FILE_FORMAT_BIT; + else + value &= ~JPEG_ENC_CTRL_FILE_FORMAT_BIT; + if (restart_interval) + value |= JPEG_ENC_CTRL_RESTART_EN_BIT; + else + value &= ~JPEG_ENC_CTRL_RESTART_EN_BIT; + writel(value, base + JPEG_ENC_CTRL); +} + +void mtk_jpeg_enc_set_config(void __iomem *base, u32 enc_format, bool exif_en, + u32 quality, u32 restart_interval) +{ + mtk_jpeg_enc_set_quality(base, quality); + + mtk_jpeg_enc_set_ctrl(base, enc_format, exif_en, restart_interval); + + writel(restart_interval, base + JPEG_ENC_RST_MCU_NUM); +} + +void mtk_jpeg_enc_start(void __iomem *base) +{ + u32 value; + + value = readl(base + JPEG_ENC_CTRL); + value |= JPEG_ENC_CTRL_INT_EN_BIT | JPEG_ENC_CTRL_ENABLE_BIT; + writel(value, base + JPEG_ENC_CTRL); +} diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h new file mode 100644 index 000000000000..73faf49b667c --- /dev/null +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Xia Jiang + * + */ + +#ifndef _MTK_JPEG_ENC_HW_H +#define _MTK_JPEG_ENC_HW_H + +#include + +#include "mtk_jpeg_core.h" + +#define JPEG_ENC_INT_STATUS_DONE BIT(0) +#define JPEG_ENC_INT_STATUS_STALL BIT(1) +#define JPEG_ENC_INT_STATUS_VCODEC_IRQ BIT(4) +#define JPEG_ENC_INT_STATUS_MASK_ALLIRQ 0x13 + +#define JPEG_ENC_DST_ADDR_OFFSET_MASK GENMASK(3, 0) +#define JPEG_ENC_QUALITY_MASK GENMASK(31, 16) + +#define JPEG_ENC_CTRL_YUV_FORMAT_MASK 0x18 +#define JPEG_ENC_CTRL_RESTART_EN_BIT BIT(10) +#define JPEG_ENC_CTRL_FILE_FORMAT_BIT BIT(5) +#define JPEG_ENC_CTRL_INT_EN_BIT BIT(2) +#define JPEG_ENC_CTRL_ENABLE_BIT BIT(0) +#define JPEG_ENC_RESET_BIT BIT(0) + +#define JPEG_ENC_YUV_FORMAT_YUYV 0 +#define JPEG_ENC_YUV_FORMAT_YVYU 1 +#define JPEG_ENC_YUV_FORMAT_NV12 2 +#define JEPG_ENC_YUV_FORMAT_NV21 3 + +#define JPEG_ENC_QUALITY_Q60 0x0 +#define JPEG_ENC_QUALITY_Q80 0x1 +#define JPEG_ENC_QUALITY_Q90 0x2 +#define JPEG_ENC_QUALITY_Q95 0x3 +#define JPEG_ENC_QUALITY_Q39 0x4 +#define JPEG_ENC_QUALITY_Q68 0x5 +#define JPEG_ENC_QUALITY_Q84 0x6 +#define JPEG_ENC_QUALITY_Q92 0x7 +#define JPEG_ENC_QUALITY_Q48 0x8 +#define JPEG_ENC_QUALITY_Q74 0xa +#define JPEG_ENC_QUALITY_Q87 0xb +#define JPEG_ENC_QUALITY_Q34 0xc +#define JPEG_ENC_QUALITY_Q64 0xe +#define JPEG_ENC_QUALITY_Q82 0xf +#define JPEG_ENC_QUALITY_Q97 0x10 + +#define JPEG_ENC_RSTB 0x100 +#define JPEG_ENC_CTRL 0x104 +#define JPEG_ENC_QUALITY 0x108 +#define JPEG_ENC_BLK_NUM 0x10C +#define JPEG_ENC_BLK_CNT 0x110 +#define JPEG_ENC_INT_STS 0x11c +#define JPEG_ENC_DST_ADDR0 0x120 +#define JPEG_ENC_DMA_ADDR0 0x124 +#define JPEG_ENC_STALL_ADDR0 0x128 +#define JPEG_ENC_OFFSET_ADDR 0x138 +#define JPEG_ENC_RST_MCU_NUM 0x150 +#define JPEG_ENC_IMG_SIZE 0x154 +#define JPEG_ENC_DEBUG_INFO0 0x160 +#define JPEG_ENC_DEBUG_INFO1 0x164 +#define JPEG_ENC_TOTAL_CYCLE 0x168 +#define JPEG_ENC_BYTE_OFFSET_MASK 0x16c +#define JPEG_ENC_SRC_LUMA_ADDR 0x170 +#define JPEG_ENC_SRC_CHROMA_ADDR 0x174 +#define JPEG_ENC_STRIDE 0x178 +#define JPEG_ENC_IMG_STRIDE 0x17c +#define JPEG_ENC_DCM_CTRL 0x300 +#define JPEG_ENC_CODEC_SEL 0x314 +#define JPEG_ENC_ULTRA_THRES 0x318 + +enum { + MTK_JPEG_ENC_RESULT_DONE, + MTK_JPEG_ENC_RESULT_STALL, + MTK_JPEG_ENC_RESULT_VCODEC_IRQ +}; + +/** + * struct mtk_jpeg_enc_qlt - JPEG encoder quality data + * @quality_param: quality value + * @hardware_value: hardware value of quality + */ +struct mtk_jpeg_enc_qlt { + u8 quality_param; + u8 hardware_value; +}; + +/** + * struct mt_jpeg_enc_bs - JPEG encoder bitstream buffer + * @dma_addr: JPEG encoder destination address + * @size: JPEG encoder bistream size + * @dma_addr_offset: JPEG encoder offset address + * @dma_addr_offsetmask: JPEG encoder destination address offset mask + */ +struct mtk_jpeg_enc_bs { + dma_addr_t dma_addr; + size_t size; + u32 dma_addr_offset; + u32 dma_addr_offsetmask; +}; + +void mtk_jpeg_enc_reset(void __iomem *base); +u32 mtk_jpeg_enc_get_and_clear_int_status(void __iomem *base); +u32 mtk_jpeg_enc_get_file_size(void __iomem *base); +u32 mtk_jpeg_enc_enum_result(void __iomem *base, u32 irq_status); +void mtk_jpeg_enc_set_img_size(void __iomem *base, u32 width, u32 height); +void mtk_jpeg_enc_set_blk_num(void __iomem *base, u32 enc_format, u32 width, + u32 height); +void mtk_jpeg_enc_set_stride(void __iomem *base, u32 enc_format, u32 width, + u32 height, u32 bytesperline); +void mtk_jpeg_enc_set_src_addr(void __iomem *base, u32 src_addr, + u32 plane_index); +void mtk_jpeg_enc_set_dst_addr(void __iomem *base, u32 dst_addr, + u32 stall_size, u32 init_offset, + u32 offset_mask); +void mtk_jpeg_enc_set_config(void __iomem *base, u32 enc_format, bool exif_en, + u32 quality, u32 restart_interval); +void mtk_jpeg_enc_start(void __iomem *enc_reg_base); + +#endif /* _MTK_JPEG_ENC_HW_H */ -- 2.18.0 _______________________________________________ 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.8 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 145D1C43331 for ; Fri, 3 Apr 2020 09:52:40 +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 D00FE20737 for ; Fri, 3 Apr 2020 09:52:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="J/bgOTUh"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="Qg1IQzZo" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D00FE20737 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=FWxgV/N5iShKdc74jLcRpkmOHP9RZXQSdA0uDWT380g=; b=J/bgOTUh8nLEqH yyA7hZBlJpGuUyo6OrimlYo/Ak9RS3n8tuSvTZVtB8dRlAh4zhVJsmUTtt24A9qzubYx3+s26tnry 2n9yB9hH1bzokBNQcruhsRngvCYATaLjdcPA+Lnr7MpXYwim347iC784omcOjEki17/Devic6DY+l 1QF7Cc9vqoVZHznkZvXJsxNZbfNlF+jtgvHpgi8JNs33gWVlJkUnUU9/vpmo7mN3dpKBaZgpxRkly uVLVC91EbYz/Q4ZCZRFSEuoRezi5iz8/nQQNBuJFC6SJPqGgGxkgpv3NgztFLTZw5DFl0XLwFkqFO k1OJkoEkMjkExFbpjhdQ==; 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 1jKJ08-00023B-My; Fri, 03 Apr 2020 09:52:36 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jKIyK-0000Eq-6U; Fri, 03 Apr 2020 09:50:48 +0000 X-UUID: e95363bf782a42fc839da6a4e612753f-20200403 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=C5GZe5ZHxZEA0bVUU+2nNLCD3vP43u8gHp5y89FHgvQ=; b=Qg1IQzZoCMcLAyHprVvm48ysqdVbeMNN/OEf+4GoxyYCYYJJNS21Vk9k3eqwB11d9qcdcEPetwFhuChyMovmZ7d7suj9OtfIwMc6GC0Ljo2APWu5+8uX6Qs8i7GM9Oe+zgPXT33L4SOVbuobJA2BkQ11gpyy/WOz418svHp4Jtk=; X-UUID: e95363bf782a42fc839da6a4e612753f-20200403 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 786733852; Fri, 03 Apr 2020 01:50:33 -0800 Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Fri, 3 Apr 2020 02:40:51 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 3 Apr 2020 17:40:48 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 3 Apr 2020 17:40:47 +0800 From: Xia Jiang To: Hans Verkuil , Mauro Carvalho Chehab , Rob Herring , "Matthias Brugger" , Rick Chang Subject: [PATCH v8 14/14] media: platform: Add jpeg dec/enc feature Date: Fri, 3 Apr 2020 17:40:33 +0800 Message-ID: <20200403094033.8288-15-xia.jiang@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20200403094033.8288-1-xia.jiang@mediatek.com> References: <20200403094033.8288-1-xia.jiang@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200403_025044_271503_84F858DD X-CRM114-Status: GOOD ( 16.34 ) 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: maoguang.meng@mediatek.com, devicetree@vger.kernel.org, mojahsu@chromium.org, srv_heupstream@mediatek.com, linux-kernel@vger.kernel.org, Tomasz Figa , senozhatsky@chromium.org, sj.huang@mediatek.com, drinkcat@chromium.org, linux-mediatek@lists.infradead.org, Xia Jiang , linux-media@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Marek Szyprowski 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 Add mtk jpeg encode v4l2 driver based on jpeg decode, because that jpeg decode and encode have great similarities with function operation. Signed-off-by: Xia Jiang --- v8:jpeg encoder and decoder use separate callbacks instead of repeating the if/else in every callback. improve vidioc_try_fmt() implementation that can be shared by jpeg encoder and decoder. fix the bug of jpeg encoder s_selection implementation. cancel the state of the jpeg encoder. improve jpeg encoder and decoder set default params flow. put the clock names and other datas in a match_data struct. fix the bug of geting correctly quality value. do the all the bits' settings of one register in one function. move the code of mtk_jpeg_enc_reg.h to mtk_jpeg_enc_hw.h and delete mtk_jpeg_enc_reg.h. v7: reverse spin lock and unlock operation in device run function for multi-instance. v6: add space to arounding '+'. alignment 'struct mtk_jpeg_fmt *fmt' match open parenthesis. change 'mtk_jpeg_enc_set_encFormat' to 'mtk_jpeg_enc_set_enc_format'. make 'mtk_jpeg_ctrls_setup' to static prototype. delete unused variables 'jpeg'/'align_h'/'align_w'/'flags'. initialize 'yuv_format'/'enc_quality' variables. v5: support crop for encoder and compose for decoder in s_selection and g_selection function. use clamp() to replace mtk_jpeg_bound_align_image() and round_up() to replace mtk_jpeg_align(). delete jpeg_enc_param/mtk_jpeg_enc_param structure and mtk_jpeg_set_param(), program the registers directly based on the original V4L2 values. move macro definition about hw to mtk_jpeg_enc_reg.h. delete unnecessary V4L2 logs in driver. cancel spin lock and unlock operation in deviec run function. change jpeg enc register offset hex numberals from upercase to lowercase. v4: split mtk_jpeg_try_fmt_mplane() to two functions, one for encoder, one for decoder. split mtk_jpeg_set_default_params() to two functions, one for encoder, one for decoder. add cropping support for encoder in g/s_selection ioctls. change exif mode support by using V4L2_JPEG_ACTIVE_MARKER_APP1. change MTK_JPEG_MAX_WIDTH/MTK_JPEG_MAX_HEIGH from 8192 to 65535 by specification. move width shifting operation behind aligning operation in mtk_jpeg_try_enc_fmt_mplane() for bug fix. fix user abuseing data_offset issue for DMABUF in mtk_jpeg_set_enc_src(). fix kbuild warings: change MTK_JPEG_MIN_HEIGHT/MTK_JPEG_MAX_HEIGHT and MTK_JPEG_MIN_WIDTH/MTK_JPEG_MAX_WIDTH from 'int' type to 'unsigned int' type. fix msleadingly indented of 'else'. v3: delete Change-Id. only test once handler->error after the last v4l2_ctrl_new_std(). seperate changes of v4l2-ctrls.c and v4l2-controls.h to new patch. v2: fix compliance test fail, check created buffer size in driver. --- drivers/media/platform/mtk-jpeg/Makefile | 5 +- .../media/platform/mtk-jpeg/mtk_jpeg_core.c | 1038 +++++++++++++---- .../media/platform/mtk-jpeg/mtk_jpeg_core.h | 51 +- .../media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h | 7 +- .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c | 193 +++ .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h | 123 ++ 6 files changed, 1188 insertions(+), 229 deletions(-) create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h diff --git a/drivers/media/platform/mtk-jpeg/Makefile b/drivers/media/platform/mtk-jpeg/Makefile index 48516dcf96e6..76c33aad0f3f 100644 --- a/drivers/media/platform/mtk-jpeg/Makefile +++ b/drivers/media/platform/mtk-jpeg/Makefile @@ -1,3 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -mtk_jpeg-objs := mtk_jpeg_core.o mtk_jpeg_dec_hw.o mtk_jpeg_dec_parse.o +mtk_jpeg-objs := mtk_jpeg_core.o \ + mtk_jpeg_dec_hw.o \ + mtk_jpeg_dec_parse.o \ + mtk_jpeg_enc_hw.o obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk_jpeg.o diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c index 77a95185584c..18a759ce2c46 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -3,6 +3,7 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ #include @@ -23,11 +24,60 @@ #include #include +#include "mtk_jpeg_enc_hw.h" #include "mtk_jpeg_dec_hw.h" #include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_parse.h" -static struct mtk_jpeg_fmt mtk_jpeg_formats[] = { +static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { + { + .fourcc = V4L2_PIX_FMT_JPEG, + .colplanes = 1, + .flags = MTK_JPEG_FMT_FLAG_ENC_CAPTURE, + }, + { + .fourcc = V4L2_PIX_FMT_NV12M, + .hw_format = JPEG_ENC_YUV_FORMAT_NV12, + .h_sample = {4, 4}, + .v_sample = {4, 2}, + .colplanes = 2, + .h_align = 4, + .v_align = 4, + .flags = MTK_JPEG_FMT_FLAG_ENC_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_NV21M, + .hw_format = JEPG_ENC_YUV_FORMAT_NV21, + .h_sample = {4, 4}, + .v_sample = {4, 2}, + .colplanes = 2, + .h_align = 4, + .v_align = 4, + .flags = MTK_JPEG_FMT_FLAG_ENC_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .hw_format = JPEG_ENC_YUV_FORMAT_YUYV, + .h_sample = {8}, + .v_sample = {4}, + .colplanes = 1, + .h_align = 5, + .v_align = 3, + .flags = MTK_JPEG_FMT_FLAG_ENC_OUTPUT, + }, + { + .fourcc = V4L2_PIX_FMT_YVYU, + .hw_format = JPEG_ENC_YUV_FORMAT_YVYU, + .h_sample = {8}, + .v_sample = {4}, + .colplanes = 1, + .h_align = 5, + .v_align = 3, + .flags = MTK_JPEG_FMT_FLAG_ENC_OUTPUT, + }, +}; + +static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { { .fourcc = V4L2_PIX_FMT_JPEG, .colplanes = 1, @@ -53,7 +103,8 @@ static struct mtk_jpeg_fmt mtk_jpeg_formats[] = { }, }; -#define MTK_JPEG_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_formats) +#define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats) +#define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats) enum { MTK_JPEG_BUF_FLAGS_INIT = 0, @@ -70,6 +121,11 @@ struct mtk_jpeg_src_buf { static int debug; module_param(debug, int, 0644); +static inline struct mtk_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl) +{ + return container_of(ctrl->handler, struct mtk_jpeg_ctx, ctrl_hdl); +} + static inline struct mtk_jpeg_ctx *mtk_jpeg_fh_to_ctx(struct v4l2_fh *fh) { return container_of(fh, struct mtk_jpeg_ctx, fh); @@ -81,12 +137,25 @@ static inline struct mtk_jpeg_src_buf *mtk_jpeg_vb2_to_srcbuf( return container_of(to_vb2_v4l2_buffer(vb), struct mtk_jpeg_src_buf, b); } -static int mtk_jpeg_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) +static int mtk_jpeg_enc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct mtk_jpeg_dev *jpeg = video_drvdata(file); + + strscpy(cap->driver, MTK_JPEG_NAME, sizeof(cap->driver)); + strscpy(cap->card, MTK_JPEG_NAME " encoder", sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", + dev_name(jpeg->dev)); + + return 0; +} + +static int mtk_jpeg_dec_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) { struct mtk_jpeg_dev *jpeg = video_drvdata(file); - strscpy(cap->driver, MTK_JPEG_NAME " decoder", sizeof(cap->driver)); + strscpy(cap->driver, MTK_JPEG_NAME, sizeof(cap->driver)); strscpy(cap->card, MTK_JPEG_NAME " decoder", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(jpeg->dev)); @@ -94,6 +163,54 @@ static int mtk_jpeg_querycap(struct file *file, void *priv, return 0; } +static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); + + switch (ctrl->id) { + case V4L2_CID_JPEG_RESTART_INTERVAL: + ctx->restart_interval = ctrl->val; + break; + case V4L2_CID_JPEG_COMPRESSION_QUALITY: + ctx->enc_quality = ctrl->val; + break; + case V4L2_CID_JPEG_ACTIVE_MARKER: + ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1 ? + true : false; + break; + } + + return 0; +} + +static const struct v4l2_ctrl_ops mtk_jpeg_enc_ctrl_ops = { + .s_ctrl = vidioc_jpeg_enc_s_ctrl, +}; + +static int mtk_jpeg_enc_ctrls_setup(struct mtk_jpeg_ctx *ctx) +{ + const struct v4l2_ctrl_ops *ops = &mtk_jpeg_enc_ctrl_ops; + struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl; + + v4l2_ctrl_handler_init(handler, 3); + + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_RESTART_INTERVAL, 0, 100, + 1, 0); + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_COMPRESSION_QUALITY, 48, + 100, 1, 90); + v4l2_ctrl_new_std(handler, ops, V4L2_CID_JPEG_ACTIVE_MARKER, 0, + V4L2_JPEG_ACTIVE_MARKER_APP1, 0, 0); + + if (handler->error) { + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); + return handler->error; + } + + v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); + + return 0; +} + static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n, struct v4l2_fmtdesc *f, u32 type) { @@ -115,117 +232,105 @@ static int mtk_jpeg_enum_fmt(struct mtk_jpeg_fmt *mtk_jpeg_formats, int n, return 0; } -static int mtk_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) +static int mtk_jpeg_enc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) { - return mtk_jpeg_enum_fmt(mtk_jpeg_formats, MTK_JPEG_NUM_FORMATS, f, + return mtk_jpeg_enum_fmt(mtk_jpeg_enc_formats, + MTK_JPEG_ENC_NUM_FORMATS, f, + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); +} + +static int mtk_jpeg_dec_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return mtk_jpeg_enum_fmt(mtk_jpeg_dec_formats, + MTK_JPEG_DEC_NUM_FORMATS, f, MTK_JPEG_FMT_FLAG_DEC_CAPTURE); } -static int mtk_jpeg_enum_fmt_vid_out(struct file *file, void *priv, - struct v4l2_fmtdesc *f) +static int mtk_jpeg_enc_enum_fmt_vid_out(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + return mtk_jpeg_enum_fmt(mtk_jpeg_enc_formats, + MTK_JPEG_ENC_NUM_FORMATS, f, + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); +} + +static int mtk_jpeg_dec_enum_fmt_vid_out(struct file *file, void *priv, + struct v4l2_fmtdesc *f) { - return mtk_jpeg_enum_fmt(mtk_jpeg_formats, MTK_JPEG_NUM_FORMATS, f, - MTK_JPEG_FMT_FLAG_DEC_OUTPUT); + return mtk_jpeg_enum_fmt(mtk_jpeg_dec_formats, MTK_JPEG_DEC_NUM_FORMATS, + f, MTK_JPEG_FMT_FLAG_DEC_OUTPUT); } -static struct mtk_jpeg_q_data *mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx, - enum v4l2_buf_type type) +static struct mtk_jpeg_q_data * +mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx, enum v4l2_buf_type type) { if (V4L2_TYPE_IS_OUTPUT(type)) return &ctx->out_q; return &ctx->cap_q; } -static struct mtk_jpeg_fmt *mtk_jpeg_find_format(struct mtk_jpeg_ctx *ctx, - u32 pixelformat, +static struct mtk_jpeg_fmt *mtk_jpeg_find_format(u32 pixelformat, unsigned int fmt_type) { - unsigned int k, fmt_flag; - - fmt_flag = (fmt_type == MTK_JPEG_FMT_TYPE_OUTPUT) ? - MTK_JPEG_FMT_FLAG_DEC_OUTPUT : - MTK_JPEG_FMT_FLAG_DEC_CAPTURE; + unsigned int k; + struct mtk_jpeg_fmt *fmt; - for (k = 0; k < MTK_JPEG_NUM_FORMATS; k++) { - struct mtk_jpeg_fmt *fmt = &mtk_jpeg_formats[k]; + for (k = 0; k < MTK_JPEG_ENC_NUM_FORMATS; k++) { + fmt = &mtk_jpeg_enc_formats[k]; - if (fmt->fourcc == pixelformat && fmt->flags & fmt_flag) + if (fmt->fourcc == pixelformat && fmt->flags & fmt_type) return fmt; } - return NULL; -} + for (k = 0; k < MTK_JPEG_DEC_NUM_FORMATS; k++) { + fmt = &mtk_jpeg_dec_formats[k]; -static void mtk_jpeg_adjust_fmt_mplane(struct mtk_jpeg_ctx *ctx, - struct v4l2_format *f) -{ - struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; - struct mtk_jpeg_q_data *q_data; - int i; - - q_data = mtk_jpeg_get_q_data(ctx, f->type); - - pix_mp->width = q_data->w; - pix_mp->height = q_data->h; - pix_mp->pixelformat = q_data->fmt->fourcc; - pix_mp->num_planes = q_data->fmt->colplanes; - - for (i = 0; i < pix_mp->num_planes; i++) { - pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i]; - pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i]; + if (fmt->fourcc == pixelformat && fmt->flags & fmt_type) + return fmt; } + + return NULL; } -static int mtk_jpeg_try_fmt_mplane(struct v4l2_format *f, - struct mtk_jpeg_fmt *fmt, - struct mtk_jpeg_ctx *ctx, int q_type) +static int vidioc_try_fmt(struct v4l2_format *f, struct mtk_jpeg_fmt *fmt) { struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; int i; - memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved)); pix_mp->field = V4L2_FIELD_NONE; - - if (ctx->state != MTK_JPEG_INIT) { - mtk_jpeg_adjust_fmt_mplane(ctx, f); - return 0; - } - pix_mp->num_planes = fmt->colplanes; pix_mp->pixelformat = fmt->fourcc; - if (q_type == MTK_JPEG_FMT_TYPE_OUTPUT) { - struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0]; - + if (fmt->fourcc == V4L2_PIX_FMT_JPEG) { pix_mp->height = clamp(pix_mp->height, MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT); pix_mp->width = clamp(pix_mp->width, MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); - - memset(pfmt->reserved, 0, sizeof(pfmt->reserved)); - pfmt->bytesperline = 0; - /* Source size must be aligned to 128 */ - pfmt->sizeimage = round_up(pfmt->sizeimage, 128); - if (pfmt->sizeimage == 0) - pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE; - return 0; + pix_mp->plane_fmt[0].bytesperline = 0; + pix_mp->plane_fmt[0].sizeimage = + round_up(pix_mp->plane_fmt[0].sizeimage, 128); + if (pix_mp->plane_fmt[0].sizeimage == 0) + pix_mp->plane_fmt[0].sizeimage = + MTK_JPEG_DEFAULT_SIZEIMAGE; + } else { + pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align), + MTK_JPEG_MIN_HEIGHT, + MTK_JPEG_MAX_HEIGHT); + pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align), + MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); + for (i = 0; i < pix_mp->num_planes; i++) { + struct v4l2_plane_pix_format *pfmt = + &pix_mp->plane_fmt[i]; + u32 stride = pix_mp->width * fmt->h_sample[i] / 4; + u32 h = pix_mp->height * fmt->v_sample[i] / 4; + + pfmt->bytesperline = stride; + pfmt->sizeimage = stride * h; + } } - /* type is MTK_JPEG_FMT_TYPE_CAPTURE */ - pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align), - MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT); - pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align), - MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); - - for (i = 0; i < fmt->colplanes; i++) { - struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i]; - u32 stride = pix_mp->width * fmt->h_sample[i] / 4; - u32 h = pix_mp->height * fmt->v_sample[i] / 4; - - pfmt->bytesperline = stride; - pfmt->sizeimage = stride * h; - } return 0; } @@ -280,14 +385,35 @@ static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv, return 0; } -static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv, - struct v4l2_format *f) +static int mtk_jpeg_enc_try_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + struct mtk_jpeg_fmt *fmt; + + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); + if (!fmt) + fmt = ctx->cap_q.fmt; + + v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n", + f->type, + (fmt->fourcc & 0xff), + (fmt->fourcc >> 8 & 0xff), + (fmt->fourcc >> 16 & 0xff), + (fmt->fourcc >> 24 & 0xff)); + + return vidioc_try_fmt(f, fmt); +} + +static int mtk_jpeg_dec_try_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) { struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); struct mtk_jpeg_fmt *fmt; - fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat, - MTK_JPEG_FMT_TYPE_CAPTURE); + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); if (!fmt) fmt = ctx->cap_q.fmt; @@ -298,17 +424,43 @@ static int mtk_jpeg_try_fmt_vid_cap_mplane(struct file *file, void *priv, (fmt->fourcc >> 16 & 0xff), (fmt->fourcc >> 24 & 0xff)); - return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_CAPTURE); + if (ctx->state != MTK_JPEG_INIT) { + mtk_jpeg_g_fmt_vid_mplane(file, priv, f); + return 0; + } + + return vidioc_try_fmt(f, fmt); +} + +static int mtk_jpeg_enc_try_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + struct mtk_jpeg_fmt *fmt; + + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); + if (!fmt) + fmt = ctx->out_q.fmt; + + v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n", + f->type, + (fmt->fourcc & 0xff), + (fmt->fourcc >> 8 & 0xff), + (fmt->fourcc >> 16 & 0xff), + (fmt->fourcc >> 24 & 0xff)); + + return vidioc_try_fmt(f, fmt); } -static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv, - struct v4l2_format *f) +static int mtk_jpeg_dec_try_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) { struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); struct mtk_jpeg_fmt *fmt; - fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat, - MTK_JPEG_FMT_TYPE_OUTPUT); + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); if (!fmt) fmt = ctx->out_q.fmt; @@ -319,17 +471,21 @@ static int mtk_jpeg_try_fmt_vid_out_mplane(struct file *file, void *priv, (fmt->fourcc >> 16 & 0xff), (fmt->fourcc >> 24 & 0xff)); - return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_OUTPUT); + if (ctx->state != MTK_JPEG_INIT) { + mtk_jpeg_g_fmt_vid_mplane(file, priv, f); + return 0; + } + + return vidioc_try_fmt(f, fmt); } static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, - struct v4l2_format *f) + struct v4l2_format *f, unsigned int fmt_type) { struct vb2_queue *vq; struct mtk_jpeg_q_data *q_data = NULL; struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; struct mtk_jpeg_dev *jpeg = ctx->jpeg; - unsigned int f_type; int i; vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); @@ -343,10 +499,7 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, return -EBUSY; } - f_type = V4L2_TYPE_IS_OUTPUT(f->type) ? - MTK_JPEG_FMT_TYPE_OUTPUT : MTK_JPEG_FMT_TYPE_CAPTURE; - - q_data->fmt = mtk_jpeg_find_format(ctx, pix_mp->pixelformat, f_type); + q_data->fmt = mtk_jpeg_find_format(pix_mp->pixelformat, fmt_type); q_data->w = pix_mp->width; q_data->h = pix_mp->height; ctx->colorspace = pix_mp->colorspace; @@ -374,28 +527,56 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, return 0; } -static int mtk_jpeg_s_fmt_vid_out_mplane(struct file *file, void *priv, - struct v4l2_format *f) +static int mtk_jpeg_enc_s_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + int ret; + + ret = mtk_jpeg_enc_try_fmt_vid_out_mplane(file, priv, f); + if (ret) + return ret; + + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); +} + +static int mtk_jpeg_dec_s_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) { int ret; - ret = mtk_jpeg_try_fmt_vid_out_mplane(file, priv, f); + ret = mtk_jpeg_dec_try_fmt_vid_out_mplane(file, priv, f); if (ret) return ret; - return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f); + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); } -static int mtk_jpeg_s_fmt_vid_cap_mplane(struct file *file, void *priv, - struct v4l2_format *f) +static int mtk_jpeg_enc_s_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) { int ret; - ret = mtk_jpeg_try_fmt_vid_cap_mplane(file, priv, f); + ret = mtk_jpeg_enc_try_fmt_vid_cap_mplane(file, priv, f); if (ret) return ret; - return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f); + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); +} + +static int mtk_jpeg_dec_s_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + int ret; + + ret = mtk_jpeg_dec_try_fmt_vid_cap_mplane(file, priv, f); + if (ret) + return ret; + + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); } static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx) @@ -420,8 +601,31 @@ static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh, return v4l2_ctrl_subscribe_event(fh, sub); } -static int mtk_jpeg_g_selection(struct file *file, void *priv, - struct v4l2_selection *s) +static int mtk_jpeg_enc_g_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + s->r.width = ctx->out_q.w; + s->r.height = ctx->out_q.h; + s->r.left = 0; + s->r.top = 0; + break; + default: + return -EINVAL; + } + return 0; +} + +static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, + struct v4l2_selection *s) { struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); @@ -446,11 +650,34 @@ static int mtk_jpeg_g_selection(struct file *file, void *priv, default: return -EINVAL; } + return 0; } -static int mtk_jpeg_s_selection(struct file *file, void *priv, - struct v4l2_selection *s) +static int mtk_jpeg_enc_s_selection(struct file *file, void *priv, + struct v4l2_selection *s) +{ + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); + + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + + switch (s->target) { + case V4L2_SEL_TGT_CROP: + s->r.left = 0; + s->r.top = 0; + ctx->out_q.w = min(s->r.width, ctx->out_q.w); + ctx->out_q.h = min(s->r.height, ctx->out_q.h); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int mtk_jpeg_dec_s_selection(struct file *file, void *priv, + struct v4l2_selection *s) { struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); @@ -467,6 +694,7 @@ static int mtk_jpeg_s_selection(struct file *file, void *priv, default: return -EINVAL; } + return 0; } @@ -495,20 +723,47 @@ static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf); } -static const struct v4l2_ioctl_ops mtk_jpeg_ioctl_ops = { - .vidioc_querycap = mtk_jpeg_querycap, - .vidioc_enum_fmt_vid_cap = mtk_jpeg_enum_fmt_vid_cap, - .vidioc_enum_fmt_vid_out = mtk_jpeg_enum_fmt_vid_out, - .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_try_fmt_vid_cap_mplane, - .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_try_fmt_vid_out_mplane, +static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = { + .vidioc_querycap = mtk_jpeg_enc_querycap, + .vidioc_enum_fmt_vid_cap = mtk_jpeg_enc_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = mtk_jpeg_enc_enum_fmt_vid_out, + .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_enc_try_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_enc_try_fmt_vid_out_mplane, + .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane, + .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane, + .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_enc_s_fmt_vid_cap_mplane, + .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_enc_s_fmt_vid_out_mplane, + .vidioc_qbuf = mtk_jpeg_qbuf, + .vidioc_subscribe_event = mtk_jpeg_subscribe_event, + .vidioc_g_selection = mtk_jpeg_enc_g_selection, + .vidioc_s_selection = mtk_jpeg_enc_s_selection, + + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +static const struct v4l2_ioctl_ops mtk_jpeg_dec_ioctl_ops = { + .vidioc_querycap = mtk_jpeg_dec_querycap, + .vidioc_enum_fmt_vid_cap = mtk_jpeg_dec_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = mtk_jpeg_dec_enum_fmt_vid_out, + .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_dec_try_fmt_vid_cap_mplane, + .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_dec_try_fmt_vid_out_mplane, .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane, .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane, - .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_s_fmt_vid_cap_mplane, - .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_s_fmt_vid_out_mplane, + .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_dec_s_fmt_vid_cap_mplane, + .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_dec_s_fmt_vid_out_mplane, .vidioc_qbuf = mtk_jpeg_qbuf, .vidioc_subscribe_event = mtk_jpeg_subscribe_event, - .vidioc_g_selection = mtk_jpeg_g_selection, - .vidioc_s_selection = mtk_jpeg_s_selection, + .vidioc_g_selection = mtk_jpeg_dec_g_selection, + .vidioc_s_selection = mtk_jpeg_dec_s_selection, .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, @@ -586,8 +841,9 @@ static bool mtk_jpeg_check_resolution_change(struct mtk_jpeg_ctx *ctx, } q_data = &ctx->cap_q; - if (q_data->fmt != mtk_jpeg_find_format(ctx, param->dst_fourcc, - MTK_JPEG_FMT_TYPE_CAPTURE)) { + if (q_data->fmt != + mtk_jpeg_find_format(param->dst_fourcc, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE)) { v4l2_dbg(1, debug, &jpeg->v4l2_dev, "format change\n"); return true; } @@ -608,9 +864,8 @@ static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx, q_data = &ctx->cap_q; q_data->w = param->dec_w; q_data->h = param->dec_h; - q_data->fmt = mtk_jpeg_find_format(ctx, - param->dst_fourcc, - MTK_JPEG_FMT_TYPE_CAPTURE); + q_data->fmt = mtk_jpeg_find_format(param->dst_fourcc, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); for (i = 0; i < q_data->fmt->colplanes; i++) { q_data->bytesperline[i] = param->mem_stride[i]; @@ -627,7 +882,18 @@ static void mtk_jpeg_set_queue_data(struct mtk_jpeg_ctx *ctx, param->dec_w, param->dec_h); } -static void mtk_jpeg_buf_queue(struct vb2_buffer *vb) +static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb) +{ + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + + v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n", + vb->vb2_queue->type, vb->index, vb); + + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb)); +} + +static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct mtk_jpeg_dec_param *param; @@ -679,7 +945,16 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); } -static void mtk_jpeg_stop_streaming(struct vb2_queue *q) +static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q) +{ + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); + struct vb2_v4l2_buffer *vb; + + while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); +} + +static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) { struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); struct vb2_v4l2_buffer *vb; @@ -705,13 +980,22 @@ static void mtk_jpeg_stop_streaming(struct vb2_queue *q) v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); } -static const struct vb2_ops mtk_jpeg_qops = { +static const struct vb2_ops mtk_jpeg_dec_qops = { .queue_setup = mtk_jpeg_queue_setup, .buf_prepare = mtk_jpeg_buf_prepare, - .buf_queue = mtk_jpeg_buf_queue, + .buf_queue = mtk_jpeg_dec_buf_queue, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, - .stop_streaming = mtk_jpeg_stop_streaming, + .stop_streaming = mtk_jpeg_dec_stop_streaming, +}; + +static const struct vb2_ops mtk_jpeg_enc_qops = { + .queue_setup = mtk_jpeg_queue_setup, + .buf_prepare = mtk_jpeg_buf_prepare, + .buf_queue = mtk_jpeg_enc_buf_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .stop_streaming = mtk_jpeg_enc_stop_streaming, }; static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx, @@ -751,7 +1035,86 @@ static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx, return 0; } -static void mtk_jpeg_device_run(void *priv) +static void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *dst_buf, + struct mtk_jpeg_enc_bs *bs) +{ + bs->dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); + bs->dma_addr_offset = ctx->enable_exif ? MTK_JPEG_DEFAULT_EXIF_SIZE : 0; + bs->dma_addr_offsetmask = bs->dma_addr & JPEG_ENC_DST_ADDR_OFFSET_MASK; + bs->size = vb2_plane_size(dst_buf, 0); + + mtk_jpeg_enc_set_dst_addr(base, bs->dma_addr, bs->size, + bs->dma_addr_offset, + bs->dma_addr_offsetmask); +} + +static void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, + struct vb2_buffer *src_buf) +{ + int i; + dma_addr_t dma_addr; + + mtk_jpeg_enc_set_img_size(base, ctx->out_q.w, ctx->out_q.h); + mtk_jpeg_enc_set_blk_num(base, ctx->out_q.fmt->fourcc, ctx->out_q.w, + ctx->out_q.h); + mtk_jpeg_enc_set_stride(base, ctx->out_q.fmt->fourcc, ctx->out_q.w, + ctx->out_q.h, ctx->out_q.bytesperline[0]); + + for (i = 0; i < src_buf->num_planes; i++) { + dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, i) + + src_buf->planes[i].data_offset; + mtk_jpeg_enc_set_src_addr(base, dma_addr, i); + } +} + +static void mtk_jpeg_enc_device_run(void *priv) +{ + struct mtk_jpeg_ctx *ctx = priv; + struct mtk_jpeg_dev *jpeg = ctx->jpeg; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + unsigned long flags; + struct mtk_jpeg_src_buf *jpeg_src_buf; + struct mtk_jpeg_enc_bs enc_bs; + int i, ret; + + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); + + if (jpeg_src_buf->flags & MTK_JPEG_BUF_FLAGS_LAST_FRAME) { + for (i = 0; i < dst_buf->vb2_buf.num_planes; i++) + vb2_set_plane_payload(&dst_buf->vb2_buf, i, 0); + buf_state = VB2_BUF_STATE_DONE; + goto enc_end; + } + + ret = pm_runtime_get_sync(jpeg->dev); + if (ret < 0) + goto enc_end; + + spin_lock_irqsave(&jpeg->hw_lock, flags); + mtk_jpeg_enc_reset(jpeg->reg_base); + + mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf, &enc_bs); + mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf); + mtk_jpeg_enc_set_config(jpeg->reg_base, ctx->out_q.fmt->hw_format, + ctx->enable_exif, ctx->enc_quality, + ctx->restart_interval); + mtk_jpeg_enc_start(jpeg->reg_base); + spin_unlock_irqrestore(&jpeg->hw_lock, flags); + return; + +enc_end: + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); +} + +static void mtk_jpeg_dec_device_run(void *priv) { struct mtk_jpeg_ctx *ctx = priv; struct mtk_jpeg_dev *jpeg = ctx->jpeg; @@ -786,15 +1149,16 @@ static void mtk_jpeg_device_run(void *priv) goto dec_end; mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs); - if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb)) + if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, + &dst_buf->vb2_buf, &fb)) goto dec_end; spin_lock_irqsave(&jpeg->hw_lock, flags); - mtk_jpeg_dec_reset(jpeg->dec_reg_base); - mtk_jpeg_dec_set_config(jpeg->dec_reg_base, + mtk_jpeg_dec_reset(jpeg->reg_base); + mtk_jpeg_dec_set_config(jpeg->reg_base, &jpeg_src_buf->dec_param, &bs, &fb); - mtk_jpeg_dec_start(jpeg->dec_reg_base); + mtk_jpeg_dec_start(jpeg->reg_base); spin_unlock_irqrestore(&jpeg->hw_lock, flags); return; @@ -806,20 +1170,30 @@ static void mtk_jpeg_device_run(void *priv) v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); } -static int mtk_jpeg_job_ready(void *priv) +static int mtk_jpeg_enc_job_ready(void *priv) +{ + return 1; +} + +static int mtk_jpeg_dec_job_ready(void *priv) { struct mtk_jpeg_ctx *ctx = priv; return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0; } -static const struct v4l2_m2m_ops mtk_jpeg_m2m_ops = { - .device_run = mtk_jpeg_device_run, - .job_ready = mtk_jpeg_job_ready, +static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = { + .device_run = mtk_jpeg_enc_device_run, + .job_ready = mtk_jpeg_enc_job_ready, }; -static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, - struct vb2_queue *dst_vq) +static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = { + .device_run = mtk_jpeg_dec_device_run, + .job_ready = mtk_jpeg_dec_job_ready, +}; + +static int mtk_jpeg_dec_queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) { struct mtk_jpeg_ctx *ctx = priv; int ret; @@ -828,7 +1202,7 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->io_modes = VB2_DMABUF | VB2_MMAP; src_vq->drv_priv = ctx; src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf); - src_vq->ops = &mtk_jpeg_qops; + src_vq->ops = &mtk_jpeg_dec_qops; src_vq->mem_ops = &vb2_dma_contig_memops; src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; src_vq->lock = &ctx->jpeg->lock; @@ -841,7 +1215,7 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; dst_vq->drv_priv = ctx; dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); - dst_vq->ops = &mtk_jpeg_qops; + dst_vq->ops = &mtk_jpeg_dec_qops; dst_vq->mem_ops = &vb2_dma_contig_memops; dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; dst_vq->lock = &ctx->jpeg->lock; @@ -851,24 +1225,112 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq, return ret; } -static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) +static int mtk_jpeg_enc_queue_init(void *priv, struct vb2_queue *src_vq, + struct vb2_queue *dst_vq) { + struct mtk_jpeg_ctx *ctx = priv; int ret; + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + src_vq->io_modes = VB2_DMABUF | VB2_MMAP; + src_vq->drv_priv = ctx; + src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf); + src_vq->ops = &mtk_jpeg_enc_qops; + src_vq->mem_ops = &vb2_dma_contig_memops; + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &ctx->jpeg->lock; + src_vq->dev = ctx->jpeg->dev; + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; + dst_vq->drv_priv = ctx; + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->ops = &mtk_jpeg_enc_qops; + dst_vq->mem_ops = &vb2_dma_contig_memops; + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->lock = &ctx->jpeg->lock; + dst_vq->dev = ctx->jpeg->dev; + ret = vb2_queue_init(dst_vq); + + return ret; +} + +static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) +{ + int ret, i; + ret = mtk_smi_larb_get(jpeg->larb); if (ret) dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret); - clk_prepare_enable(jpeg->clk_jdec_smi); - clk_prepare_enable(jpeg->clk_jdec); + + for (i = 0; i < jpeg->variant->num_clocks; i++) { + ret = clk_prepare_enable(jpeg->clocks[i]); + if (ret) { + while (--i >= 0) + clk_disable_unprepare(jpeg->clocks[i]); + } + } } static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) { - clk_disable_unprepare(jpeg->clk_jdec); - clk_disable_unprepare(jpeg->clk_jdec_smi); + int i; + + for (i = jpeg->variant->num_clocks - 1; i >= 0; i--) + clk_disable_unprepare(jpeg->clocks[i]); mtk_smi_larb_put(jpeg->larb); } +static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv) +{ + struct mtk_jpeg_dev *jpeg = priv; + struct mtk_jpeg_ctx *ctx; + struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct mtk_jpeg_src_buf *jpeg_src_buf; + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; + u32 enc_irq_ret; + u32 enc_ret, result_size; + + spin_lock(&jpeg->hw_lock); + + ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); + if (!ctx) { + v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); + return IRQ_HANDLED; + } + + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); + + enc_ret = mtk_jpeg_enc_get_and_clear_int_status(jpeg->reg_base); + enc_irq_ret = mtk_jpeg_enc_enum_result(jpeg->reg_base, enc_ret); + + if (enc_irq_ret >= MTK_JPEG_ENC_RESULT_STALL) + mtk_jpeg_enc_reset(jpeg->reg_base); + + if (enc_irq_ret != MTK_JPEG_ENC_RESULT_DONE) { + dev_err(jpeg->dev, "encode failed\n"); + goto enc_end; + } + + result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); + vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); + + buf_state = VB2_BUF_STATE_DONE; + +enc_end: + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); + spin_unlock(&jpeg->hw_lock); + pm_runtime_put_sync(ctx->jpeg->dev); + return IRQ_HANDLED; +} + static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) { struct mtk_jpeg_dev *jpeg = priv; @@ -876,13 +1338,13 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) struct vb2_v4l2_buffer *src_buf, *dst_buf; struct mtk_jpeg_src_buf *jpeg_src_buf; enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; - u32 dec_irq_ret; + u32 dec_irq_ret; u32 dec_ret; int i; spin_lock(&jpeg->hw_lock); - dec_ret = mtk_jpeg_dec_get_int_status(jpeg->dec_reg_base); + dec_ret = mtk_jpeg_dec_get_int_status(jpeg->reg_base); dec_irq_ret = mtk_jpeg_dec_enum_result(dec_ret); ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); if (!ctx) { @@ -895,7 +1357,7 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW) - mtk_jpeg_dec_reset(jpeg->dec_reg_base); + mtk_jpeg_dec_reset(jpeg->reg_base); if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) { dev_err(jpeg->dev, "decode failed\n"); @@ -917,39 +1379,131 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) return IRQ_HANDLED; } -static void mtk_jpeg_set_default_params(struct mtk_jpeg_ctx *ctx) +static void mtk_jpeg_set_enc_default_params(struct mtk_jpeg_ctx *ctx) { struct mtk_jpeg_q_data *q = &ctx->out_q; - int i; + struct v4l2_pix_format_mplane *pix_mp; + + pix_mp = kmalloc(sizeof(*pix_mp), GFP_KERNEL); + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; ctx->colorspace = V4L2_COLORSPACE_JPEG, ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; ctx->quantization = V4L2_QUANTIZATION_DEFAULT; ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; - - q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG, - MTK_JPEG_FMT_TYPE_OUTPUT); - q->w = MTK_JPEG_MIN_WIDTH; - q->h = MTK_JPEG_MIN_HEIGHT; - q->bytesperline[0] = 0; - q->sizeimage[0] = MTK_JPEG_DEFAULT_SIZEIMAGE; + pix_mp->width = MTK_JPEG_MIN_WIDTH; + pix_mp->height = MTK_JPEG_MIN_HEIGHT; + + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_YUYV, + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, + fmt.pix_mp), q->fmt); + q->w = pix_mp->width; + q->h = pix_mp->height; + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; q = &ctx->cap_q; - q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_YUV420M, - MTK_JPEG_FMT_TYPE_CAPTURE); - q->w = MTK_JPEG_MIN_WIDTH; - q->h = MTK_JPEG_MIN_HEIGHT; + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_JPEG, + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); + pix_mp->width = MTK_JPEG_MIN_WIDTH; + pix_mp->height = MTK_JPEG_MIN_HEIGHT; + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, + fmt.pix_mp), q->fmt); + q->w = pix_mp->width; + q->h = pix_mp->height; + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; +} + +static void mtk_jpeg_set_dec_default_params(struct mtk_jpeg_ctx *ctx) +{ + struct mtk_jpeg_q_data *q = &ctx->out_q; + struct v4l2_pix_format_mplane *pix_mp; + int i; + + pix_mp = kmalloc(sizeof(*pix_mp), GFP_KERNEL); + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; + ctx->colorspace = V4L2_COLORSPACE_JPEG, + ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + ctx->quantization = V4L2_QUANTIZATION_DEFAULT; + ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; + pix_mp->width = MTK_JPEG_MIN_WIDTH; + pix_mp->height = MTK_JPEG_MIN_HEIGHT; + + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_JPEG, + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, + fmt.pix_mp), q->fmt); + q->w = pix_mp->width; + q->h = pix_mp->height; + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; + + q = &ctx->cap_q; + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_YUV420M, + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); + pix_mp->width = MTK_JPEG_MIN_WIDTH; + pix_mp->height = MTK_JPEG_MIN_HEIGHT; + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, + fmt.pix_mp), q->fmt); + q->w = pix_mp->width; + q->h = pix_mp->height; for (i = 0; i < q->fmt->colplanes; i++) { - u32 stride = q->w * q->fmt->h_sample[i] / 4; - u32 h = q->h * q->fmt->v_sample[i] / 4; + q->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage; + q->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline; + } +} + +static int mtk_jpeg_enc_open(struct file *file) +{ + struct mtk_jpeg_dev *jpeg = video_drvdata(file); + struct video_device *vfd = video_devdata(file); + struct mtk_jpeg_ctx *ctx; + int ret = 0; - q->bytesperline[i] = stride; - q->sizeimage[i] = stride * h; + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + if (mutex_lock_interruptible(&jpeg->lock)) { + ret = -ERESTARTSYS; + goto free; + } + + v4l2_fh_init(&ctx->fh, vfd); + file->private_data = &ctx->fh; + v4l2_fh_add(&ctx->fh); + + ctx->jpeg = jpeg; + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, + mtk_jpeg_enc_queue_init); + if (IS_ERR(ctx->fh.m2m_ctx)) { + ret = PTR_ERR(ctx->fh.m2m_ctx); + goto error; } + + ret = mtk_jpeg_enc_ctrls_setup(ctx); + if (ret) { + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n"); + goto error; + } + mtk_jpeg_set_enc_default_params(ctx); + + mutex_unlock(&jpeg->lock); + return 0; + +error: + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + mutex_unlock(&jpeg->lock); +free: + kfree(ctx); + return ret; } -static int mtk_jpeg_open(struct file *file) +static int mtk_jpeg_dec_open(struct file *file) { struct mtk_jpeg_dev *jpeg = video_drvdata(file); struct video_device *vfd = video_devdata(file); @@ -971,13 +1525,20 @@ static int mtk_jpeg_open(struct file *file) ctx->jpeg = jpeg; ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, - mtk_jpeg_queue_init); + mtk_jpeg_dec_queue_init); if (IS_ERR(ctx->fh.m2m_ctx)) { ret = PTR_ERR(ctx->fh.m2m_ctx); goto error; } - mtk_jpeg_set_default_params(ctx); + v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0); + ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); + if (ret) { + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg dec controls\n"); + goto error; + } + mtk_jpeg_set_dec_default_params(ctx); + mutex_unlock(&jpeg->lock); return 0; @@ -997,6 +1558,7 @@ static int mtk_jpeg_release(struct file *file) mutex_lock(&jpeg->lock); v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); kfree(ctx); @@ -1004,9 +1566,18 @@ static int mtk_jpeg_release(struct file *file) return 0; } -static const struct v4l2_file_operations mtk_jpeg_fops = { +static const struct v4l2_file_operations mtk_jpeg_enc_fops = { .owner = THIS_MODULE, - .open = mtk_jpeg_open, + .open = mtk_jpeg_enc_open, + .release = mtk_jpeg_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static const struct v4l2_file_operations mtk_jpeg_dec_fops = { + .owner = THIS_MODULE, + .open = mtk_jpeg_dec_open, .release = mtk_jpeg_release, .poll = v4l2_m2m_fop_poll, .unlocked_ioctl = video_ioctl2, @@ -1017,6 +1588,7 @@ static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg) { struct device_node *node; struct platform_device *pdev; + int i; node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0); if (!node) @@ -1030,19 +1602,24 @@ static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg) jpeg->larb = &pdev->dev; - jpeg->clk_jdec = devm_clk_get(jpeg->dev, "jpgdec"); - if (IS_ERR(jpeg->clk_jdec)) - return PTR_ERR(jpeg->clk_jdec); + for (i = 0; i < jpeg->variant->num_clocks; i++) { + jpeg->clocks[i] = devm_clk_get(jpeg->dev, + jpeg->variant->clk_names[i]); + if (IS_ERR(jpeg->clocks[i])) { + dev_err(&pdev->dev, "failed to get clock: %s\n", + jpeg->variant->clk_names[i]); + return PTR_ERR(jpeg->clocks[i]); + } + } - jpeg->clk_jdec_smi = devm_clk_get(jpeg->dev, "jpgdec-smi"); - return PTR_ERR_OR_ZERO(jpeg->clk_jdec_smi); + return 0; } static int mtk_jpeg_probe(struct platform_device *pdev) { struct mtk_jpeg_dev *jpeg; struct resource *res; - int dec_irq; + int jpeg_irq; int ret; jpeg = devm_kzalloc(&pdev->dev, sizeof(*jpeg), GFP_KERNEL); @@ -1052,25 +1629,30 @@ static int mtk_jpeg_probe(struct platform_device *pdev) mutex_init(&jpeg->lock); spin_lock_init(&jpeg->hw_lock); jpeg->dev = &pdev->dev; + jpeg->variant = of_device_get_match_data(jpeg->dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - jpeg->dec_reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(jpeg->dec_reg_base)) { - ret = PTR_ERR(jpeg->dec_reg_base); + jpeg->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(jpeg->reg_base)) { + ret = PTR_ERR(jpeg->reg_base); return ret; } - dec_irq = platform_get_irq(pdev, 0); - if (dec_irq < 0) { - dev_err(&pdev->dev, "Failed to get dec_irq %d.\n", dec_irq); - return dec_irq; + jpeg_irq = platform_get_irq(pdev, 0); + if (jpeg_irq < 0) { + dev_err(&pdev->dev, "Failed to get jpeg_irq %d.\n", jpeg_irq); + return jpeg_irq; } - ret = devm_request_irq(&pdev->dev, dec_irq, mtk_jpeg_dec_irq, 0, - pdev->name, jpeg); + if (jpeg->variant->is_encoder) + ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_enc_irq, + 0, pdev->name, jpeg); + else + ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_dec_irq, + 0, pdev->name, jpeg); if (ret) { - dev_err(&pdev->dev, "Failed to request dec_irq %d (%d)\n", - dec_irq, ret); + dev_err(&pdev->dev, "Failed to request jpeg_irq %d (%d)\n", + jpeg_irq, ret); goto err_req_irq; } @@ -1087,40 +1669,50 @@ static int mtk_jpeg_probe(struct platform_device *pdev) goto err_dev_register; } - jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_m2m_ops); + if (jpeg->variant->is_encoder) + jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_enc_m2m_ops); + else + jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_dec_m2m_ops); if (IS_ERR(jpeg->m2m_dev)) { v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n"); ret = PTR_ERR(jpeg->m2m_dev); goto err_m2m_init; } - jpeg->dec_vdev = video_device_alloc(); - if (!jpeg->dec_vdev) { + jpeg->vdev = video_device_alloc(); + if (!jpeg->vdev) { ret = -ENOMEM; - goto err_dec_vdev_alloc; + goto err_vfd_jpeg_alloc; } - snprintf(jpeg->dec_vdev->name, sizeof(jpeg->dec_vdev->name), - "%s-dec", MTK_JPEG_NAME); - jpeg->dec_vdev->fops = &mtk_jpeg_fops; - jpeg->dec_vdev->ioctl_ops = &mtk_jpeg_ioctl_ops; - jpeg->dec_vdev->minor = -1; - jpeg->dec_vdev->release = video_device_release; - jpeg->dec_vdev->lock = &jpeg->lock; - jpeg->dec_vdev->v4l2_dev = &jpeg->v4l2_dev; - jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M; - jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING | + snprintf(jpeg->vdev->name, sizeof(jpeg->vdev->name), + "%s-%s", MTK_JPEG_NAME, + jpeg->variant->is_encoder ? "enc" : "dec"); + if (jpeg->variant->is_encoder) { + jpeg->vdev->fops = &mtk_jpeg_enc_fops; + jpeg->vdev->ioctl_ops = &mtk_jpeg_enc_ioctl_ops; + } else { + jpeg->vdev->fops = &mtk_jpeg_dec_fops; + jpeg->vdev->ioctl_ops = &mtk_jpeg_dec_ioctl_ops; + } + jpeg->vdev->minor = -1; + jpeg->vdev->release = video_device_release; + jpeg->vdev->lock = &jpeg->lock; + jpeg->vdev->v4l2_dev = &jpeg->v4l2_dev; + jpeg->vdev->vfl_dir = VFL_DIR_M2M; + jpeg->vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; - ret = video_register_device(jpeg->dec_vdev, VFL_TYPE_GRABBER, -1); + ret = video_register_device(jpeg->vdev, VFL_TYPE_GRABBER, -1); if (ret) { v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n"); - goto err_dec_vdev_register; + goto err_vfd_jpeg_register; } - video_set_drvdata(jpeg->dec_vdev, jpeg); + video_set_drvdata(jpeg->vdev, jpeg); v4l2_info(&jpeg->v4l2_dev, - "decoder device registered as /dev/video%d (%d,%d)\n", - jpeg->dec_vdev->num, VIDEO_MAJOR, jpeg->dec_vdev->minor); + "jpeg %s device registered as /dev/video%d (%d,%d)\n", + jpeg->variant->is_encoder ? "enc" : "dec", jpeg->vdev->num, + VIDEO_MAJOR, jpeg->vdev->minor); platform_set_drvdata(pdev, jpeg); @@ -1128,10 +1720,10 @@ static int mtk_jpeg_probe(struct platform_device *pdev) return 0; -err_dec_vdev_register: - video_device_release(jpeg->dec_vdev); +err_vfd_jpeg_register: + video_device_release(jpeg->vdev); -err_dec_vdev_alloc: +err_vfd_jpeg_alloc: v4l2_m2m_release(jpeg->m2m_dev); err_m2m_init: @@ -1151,8 +1743,8 @@ static int mtk_jpeg_remove(struct platform_device *pdev) struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); - video_unregister_device(jpeg->dec_vdev); - video_device_release(jpeg->dec_vdev); + video_unregister_device(jpeg->vdev); + video_device_release(jpeg->vdev); v4l2_m2m_release(jpeg->m2m_dev); v4l2_device_unregister(&jpeg->v4l2_dev); @@ -1211,14 +1803,36 @@ static const struct dev_pm_ops mtk_jpeg_pm_ops = { SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL) }; +static struct mtk_jpeg_variant mt8173_jpeg_drvdata = { + .is_encoder = false, + .clk_names = {"jpgdec-smi", "jpgdec"}, + .num_clocks = 2, +}; + +static struct mtk_jpeg_variant mt2701_jpeg_drvdata = { + .is_encoder = false, + .clk_names = {"jpgdec-smi", "jpgdec"}, + .num_clocks = 2, +}; + +static struct mtk_jpeg_variant mtk_jpeg_drvdata = { + .is_encoder = true, + .clk_names = {"jpgenc"}, + .num_clocks = 1, +}; + static const struct of_device_id mtk_jpeg_match[] = { { .compatible = "mediatek,mt8173-jpgdec", - .data = NULL, + .data = &mt8173_jpeg_drvdata, }, { .compatible = "mediatek,mt2701-jpgdec", - .data = NULL, + .data = &mt2701_jpeg_drvdata, + }, + { + .compatible = "mediatek,mtk-jpgenc", + .data = &mtk_jpeg_drvdata, }, {}, }; diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h index 9bbd615b1067..8f80f2a69d45 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h @@ -3,6 +3,7 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ #ifndef _MTK_JPEG_CORE_H @@ -16,19 +17,21 @@ #define MTK_JPEG_NAME "mtk-jpeg" #define MTK_JPEG_COMP_MAX 3 +#define MTK_JPEG_MAX_CLOCKS 2 + #define MTK_JPEG_FMT_FLAG_DEC_OUTPUT BIT(0) #define MTK_JPEG_FMT_FLAG_DEC_CAPTURE BIT(1) - -#define MTK_JPEG_FMT_TYPE_OUTPUT 1 -#define MTK_JPEG_FMT_TYPE_CAPTURE 2 +#define MTK_JPEG_FMT_FLAG_ENC_OUTPUT BIT(2) +#define MTK_JPEG_FMT_FLAG_ENC_CAPTURE BIT(3) #define MTK_JPEG_MIN_WIDTH 32U #define MTK_JPEG_MIN_HEIGHT 32U -#define MTK_JPEG_MAX_WIDTH 8192U -#define MTK_JPEG_MAX_HEIGHT 8192U +#define MTK_JPEG_MAX_WIDTH 65535U +#define MTK_JPEG_MAX_HEIGHT 65535U #define MTK_JPEG_DEFAULT_SIZEIMAGE (1 * 1024 * 1024) +#define MTK_JPEG_DEFAULT_EXIF_SIZE (64 * 1024) /** * enum mtk_jpeg_ctx_state - contex state of jpeg @@ -39,6 +42,18 @@ enum mtk_jpeg_ctx_state { MTK_JPEG_SOURCE_CHANGE, }; +/** + * mtk_jpeg_variant - mtk jpeg driver variant + * @is_encoder: driver mode is jpeg encoder + * @clk_names: clock names + * @num_clocks: numbers of clock + */ +struct mtk_jpeg_variant { + bool is_encoder; + const char *clk_names[MTK_JPEG_MAX_CLOCKS]; + int num_clocks; +}; + /** * struct mt_jpeg - JPEG IP abstraction * @lock: the mutex protecting this structure @@ -48,11 +63,11 @@ enum mtk_jpeg_ctx_state { * @v4l2_dev: v4l2 device for mem2mem mode * @m2m_dev: v4l2 mem2mem device data * @alloc_ctx: videobuf2 memory allocator's context - * @dec_vdev: video device node for decoder mem2mem mode - * @dec_reg_base: JPEG registers mapping - * @clk_jdec: JPEG hw working clock - * @clk_jdec_smi: JPEG SMI bus clock + * @vdev: video device node for jpeg mem2mem mode + * @reg_base: JPEG registers mapping * @larb: SMI device + * @clocks: JPEG IP clock(s) + * @variant: driver variant to be used */ struct mtk_jpeg_dev { struct mutex lock; @@ -62,16 +77,17 @@ struct mtk_jpeg_dev { struct v4l2_device v4l2_dev; struct v4l2_m2m_dev *m2m_dev; void *alloc_ctx; - struct video_device *dec_vdev; - void __iomem *dec_reg_base; - struct clk *clk_jdec; - struct clk *clk_jdec_smi; + struct video_device *vdev; + void __iomem *reg_base; struct device *larb; + struct clk *clocks[MTK_JPEG_MAX_CLOCKS]; + const struct mtk_jpeg_variant *variant; }; /** * struct jpeg_fmt - driver's internal color format data * @fourcc: the fourcc code, 0 if not applicable + * @hw_format: hardware format value * @h_sample: horizontal sample count of plane in 4 * 4 pixel image * @v_sample: vertical sample count of plane in 4 * 4 pixel image * @colplanes: number of color planes (1 for packed formats) @@ -81,6 +97,7 @@ struct mtk_jpeg_dev { */ struct mtk_jpeg_fmt { u32 fourcc; + u32 hw_format; int h_sample[VIDEO_MAX_PLANES]; int v_sample[VIDEO_MAX_PLANES]; int colplanes; @@ -113,6 +130,10 @@ struct mtk_jpeg_q_data { * @cap_q: destination (capture) queue queue information * @fh: V4L2 file handle * @state: state of the context + * @enable_exif: enable exif mode of jpeg encoder + * @enc_quality: jpeg encoder quality + * @restart_interval: jpeg encoder restart interval + * @ctrl_hdl: controls handler * @colorspace: enum v4l2_colorspace; supplemental to pixelformat * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding * @quantization: enum v4l2_quantization, colorspace quantization @@ -124,6 +145,10 @@ struct mtk_jpeg_ctx { struct mtk_jpeg_q_data cap_q; struct v4l2_fh fh; enum mtk_jpeg_ctx_state state; + bool enable_exif; + u8 enc_quality; + u8 restart_interval; + struct v4l2_ctrl_handler ctrl_hdl; enum v4l2_colorspace colorspace; enum v4l2_ycbcr_encoding ycbcr_enc; diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h index 1cc37dbfc8e7..ce263db5f30a 100644 --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h @@ -3,10 +3,11 @@ * Copyright (c) 2016 MediaTek Inc. * Author: Ming Hsiu Tsai * Rick Chang + * Xia Jiang */ -#ifndef _MTK_JPEG_HW_H -#define _MTK_JPEG_HW_H +#ifndef _MTK_JPEG_DEC_HW_H +#define _MTK_JPEG_DEC_HW_H #include @@ -75,4 +76,4 @@ void mtk_jpeg_dec_set_config(void __iomem *base, void mtk_jpeg_dec_reset(void __iomem *dec_reg_base); void mtk_jpeg_dec_start(void __iomem *dec_reg_base); -#endif /* _MTK_JPEG_HW_H */ +#endif /* _MTK_JPEG_DEC_HW_H */ diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c new file mode 100644 index 000000000000..7fc1de920a75 --- /dev/null +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Xia Jiang + * + */ + +#include +#include +#include + +#include "mtk_jpeg_enc_hw.h" + +static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { + {.quality_param = 34, .hardware_value = JPEG_ENC_QUALITY_Q34}, + {.quality_param = 39, .hardware_value = JPEG_ENC_QUALITY_Q39}, + {.quality_param = 48, .hardware_value = JPEG_ENC_QUALITY_Q48}, + {.quality_param = 60, .hardware_value = JPEG_ENC_QUALITY_Q60}, + {.quality_param = 64, .hardware_value = JPEG_ENC_QUALITY_Q64}, + {.quality_param = 68, .hardware_value = JPEG_ENC_QUALITY_Q68}, + {.quality_param = 74, .hardware_value = JPEG_ENC_QUALITY_Q74}, + {.quality_param = 80, .hardware_value = JPEG_ENC_QUALITY_Q80}, + {.quality_param = 82, .hardware_value = JPEG_ENC_QUALITY_Q82}, + {.quality_param = 84, .hardware_value = JPEG_ENC_QUALITY_Q84}, + {.quality_param = 87, .hardware_value = JPEG_ENC_QUALITY_Q87}, + {.quality_param = 90, .hardware_value = JPEG_ENC_QUALITY_Q90}, + {.quality_param = 92, .hardware_value = JPEG_ENC_QUALITY_Q92}, + {.quality_param = 95, .hardware_value = JPEG_ENC_QUALITY_Q95}, + {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, +}; + +void mtk_jpeg_enc_reset(void __iomem *base) +{ + writel(0x00, base + JPEG_ENC_RSTB); + writel(JPEG_ENC_RESET_BIT, base + JPEG_ENC_RSTB); + writel(0x00, base + JPEG_ENC_CODEC_SEL); +} + +u32 mtk_jpeg_enc_get_and_clear_int_status(void __iomem *base) +{ + u32 ret; + + ret = readl(base + JPEG_ENC_INT_STS) & + JPEG_ENC_INT_STATUS_MASK_ALLIRQ; + if (ret) + writel(0, base + JPEG_ENC_INT_STS); + + return ret; +} + +u32 mtk_jpeg_enc_get_file_size(void __iomem *base) +{ + return readl(base + JPEG_ENC_DMA_ADDR0) - + readl(base + JPEG_ENC_DST_ADDR0); +} + +u32 mtk_jpeg_enc_enum_result(void __iomem *base, u32 irq_status) +{ + if (irq_status & JPEG_ENC_INT_STATUS_DONE) + return MTK_JPEG_ENC_RESULT_DONE; + else if (irq_status & JPEG_ENC_INT_STATUS_STALL) + return MTK_JPEG_ENC_RESULT_STALL; + else + return MTK_JPEG_ENC_RESULT_VCODEC_IRQ; +} + +void mtk_jpeg_enc_set_img_size(void __iomem *base, u32 width, u32 height) +{ + u32 value; + + value = width << 16 | height; + writel(value, base + JPEG_ENC_IMG_SIZE); +} + +void mtk_jpeg_enc_set_blk_num(void __iomem *base, u32 enc_format, u32 width, + u32 height) +{ + u32 blk_num; + u32 is_420; + u32 padding_width; + u32 padding_height; + u32 luma_blocks; + u32 chroma_blocks; + + is_420 = (enc_format == V4L2_PIX_FMT_NV12M || + enc_format == V4L2_PIX_FMT_NV21M) ? 1 : 0; + padding_width = round_up(width, 16); + padding_height = round_up(height, is_420 ? 16 : 8); + + luma_blocks = padding_width / 8 * padding_height / 8; + if (is_420) + chroma_blocks = luma_blocks / 4; + else + chroma_blocks = luma_blocks / 2; + + blk_num = luma_blocks + 2 * chroma_blocks - 1; + + writel(blk_num, base + JPEG_ENC_BLK_NUM); +} + +void mtk_jpeg_enc_set_stride(void __iomem *base, u32 enc_format, u32 width, + u32 height, u32 bytesperline) +{ + u32 img_stride; + u32 mem_stride; + + if (enc_format == V4L2_PIX_FMT_NV12M || + enc_format == V4L2_PIX_FMT_NV21M) { + img_stride = round_up(width, 16); + mem_stride = bytesperline; + } else { + img_stride = round_up(width * 2, 32); + mem_stride = img_stride; + } + + writel(img_stride, base + JPEG_ENC_IMG_STRIDE); + writel(mem_stride, base + JPEG_ENC_STRIDE); +} + +void mtk_jpeg_enc_set_src_addr(void __iomem *base, u32 src_addr, + u32 plane_index) +{ + if (!plane_index) + writel(src_addr, base + JPEG_ENC_SRC_LUMA_ADDR); + else + writel(src_addr, base + JPEG_ENC_SRC_CHROMA_ADDR); +} + +void mtk_jpeg_enc_set_dst_addr(void __iomem *base, u32 dst_addr, + u32 stall_size, u32 init_offset, + u32 offset_mask) +{ + writel(init_offset & ~0xf, base + JPEG_ENC_OFFSET_ADDR); + writel(offset_mask & 0xf, base + JPEG_ENC_BYTE_OFFSET_MASK); + writel(dst_addr & ~0xf, base + JPEG_ENC_DST_ADDR0); + writel((dst_addr + stall_size) & ~0xf, base + JPEG_ENC_STALL_ADDR0); +} + +static void mtk_jpeg_enc_set_quality(void __iomem *base, u32 quality) +{ + u32 value; + u32 i, enc_quality; + + enc_quality = mtk_jpeg_enc_quality[0].hardware_value; + for (i = 0; i < ARRAY_SIZE(mtk_jpeg_enc_quality); i++) { + if (quality <= mtk_jpeg_enc_quality[i].quality_param) { + enc_quality = mtk_jpeg_enc_quality[i].hardware_value; + break; + } + } + + value = readl(base + JPEG_ENC_QUALITY); + value = (value & JPEG_ENC_QUALITY_MASK) | enc_quality; + writel(value, base + JPEG_ENC_QUALITY); +} + +static void mtk_jpeg_enc_set_ctrl(void __iomem *base, u32 enc_format, + bool exif_en, u32 restart_interval) +{ + u32 value; + + value = readl(base + JPEG_ENC_CTRL); + value &= ~JPEG_ENC_CTRL_YUV_FORMAT_MASK; + value |= (enc_format & 3) << 3; + if (exif_en) + value |= JPEG_ENC_CTRL_FILE_FORMAT_BIT; + else + value &= ~JPEG_ENC_CTRL_FILE_FORMAT_BIT; + if (restart_interval) + value |= JPEG_ENC_CTRL_RESTART_EN_BIT; + else + value &= ~JPEG_ENC_CTRL_RESTART_EN_BIT; + writel(value, base + JPEG_ENC_CTRL); +} + +void mtk_jpeg_enc_set_config(void __iomem *base, u32 enc_format, bool exif_en, + u32 quality, u32 restart_interval) +{ + mtk_jpeg_enc_set_quality(base, quality); + + mtk_jpeg_enc_set_ctrl(base, enc_format, exif_en, restart_interval); + + writel(restart_interval, base + JPEG_ENC_RST_MCU_NUM); +} + +void mtk_jpeg_enc_start(void __iomem *base) +{ + u32 value; + + value = readl(base + JPEG_ENC_CTRL); + value |= JPEG_ENC_CTRL_INT_EN_BIT | JPEG_ENC_CTRL_ENABLE_BIT; + writel(value, base + JPEG_ENC_CTRL); +} diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h new file mode 100644 index 000000000000..73faf49b667c --- /dev/null +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Xia Jiang + * + */ + +#ifndef _MTK_JPEG_ENC_HW_H +#define _MTK_JPEG_ENC_HW_H + +#include + +#include "mtk_jpeg_core.h" + +#define JPEG_ENC_INT_STATUS_DONE BIT(0) +#define JPEG_ENC_INT_STATUS_STALL BIT(1) +#define JPEG_ENC_INT_STATUS_VCODEC_IRQ BIT(4) +#define JPEG_ENC_INT_STATUS_MASK_ALLIRQ 0x13 + +#define JPEG_ENC_DST_ADDR_OFFSET_MASK GENMASK(3, 0) +#define JPEG_ENC_QUALITY_MASK GENMASK(31, 16) + +#define JPEG_ENC_CTRL_YUV_FORMAT_MASK 0x18 +#define JPEG_ENC_CTRL_RESTART_EN_BIT BIT(10) +#define JPEG_ENC_CTRL_FILE_FORMAT_BIT BIT(5) +#define JPEG_ENC_CTRL_INT_EN_BIT BIT(2) +#define JPEG_ENC_CTRL_ENABLE_BIT BIT(0) +#define JPEG_ENC_RESET_BIT BIT(0) + +#define JPEG_ENC_YUV_FORMAT_YUYV 0 +#define JPEG_ENC_YUV_FORMAT_YVYU 1 +#define JPEG_ENC_YUV_FORMAT_NV12 2 +#define JEPG_ENC_YUV_FORMAT_NV21 3 + +#define JPEG_ENC_QUALITY_Q60 0x0 +#define JPEG_ENC_QUALITY_Q80 0x1 +#define JPEG_ENC_QUALITY_Q90 0x2 +#define JPEG_ENC_QUALITY_Q95 0x3 +#define JPEG_ENC_QUALITY_Q39 0x4 +#define JPEG_ENC_QUALITY_Q68 0x5 +#define JPEG_ENC_QUALITY_Q84 0x6 +#define JPEG_ENC_QUALITY_Q92 0x7 +#define JPEG_ENC_QUALITY_Q48 0x8 +#define JPEG_ENC_QUALITY_Q74 0xa +#define JPEG_ENC_QUALITY_Q87 0xb +#define JPEG_ENC_QUALITY_Q34 0xc +#define JPEG_ENC_QUALITY_Q64 0xe +#define JPEG_ENC_QUALITY_Q82 0xf +#define JPEG_ENC_QUALITY_Q97 0x10 + +#define JPEG_ENC_RSTB 0x100 +#define JPEG_ENC_CTRL 0x104 +#define JPEG_ENC_QUALITY 0x108 +#define JPEG_ENC_BLK_NUM 0x10C +#define JPEG_ENC_BLK_CNT 0x110 +#define JPEG_ENC_INT_STS 0x11c +#define JPEG_ENC_DST_ADDR0 0x120 +#define JPEG_ENC_DMA_ADDR0 0x124 +#define JPEG_ENC_STALL_ADDR0 0x128 +#define JPEG_ENC_OFFSET_ADDR 0x138 +#define JPEG_ENC_RST_MCU_NUM 0x150 +#define JPEG_ENC_IMG_SIZE 0x154 +#define JPEG_ENC_DEBUG_INFO0 0x160 +#define JPEG_ENC_DEBUG_INFO1 0x164 +#define JPEG_ENC_TOTAL_CYCLE 0x168 +#define JPEG_ENC_BYTE_OFFSET_MASK 0x16c +#define JPEG_ENC_SRC_LUMA_ADDR 0x170 +#define JPEG_ENC_SRC_CHROMA_ADDR 0x174 +#define JPEG_ENC_STRIDE 0x178 +#define JPEG_ENC_IMG_STRIDE 0x17c +#define JPEG_ENC_DCM_CTRL 0x300 +#define JPEG_ENC_CODEC_SEL 0x314 +#define JPEG_ENC_ULTRA_THRES 0x318 + +enum { + MTK_JPEG_ENC_RESULT_DONE, + MTK_JPEG_ENC_RESULT_STALL, + MTK_JPEG_ENC_RESULT_VCODEC_IRQ +}; + +/** + * struct mtk_jpeg_enc_qlt - JPEG encoder quality data + * @quality_param: quality value + * @hardware_value: hardware value of quality + */ +struct mtk_jpeg_enc_qlt { + u8 quality_param; + u8 hardware_value; +}; + +/** + * struct mt_jpeg_enc_bs - JPEG encoder bitstream buffer + * @dma_addr: JPEG encoder destination address + * @size: JPEG encoder bistream size + * @dma_addr_offset: JPEG encoder offset address + * @dma_addr_offsetmask: JPEG encoder destination address offset mask + */ +struct mtk_jpeg_enc_bs { + dma_addr_t dma_addr; + size_t size; + u32 dma_addr_offset; + u32 dma_addr_offsetmask; +}; + +void mtk_jpeg_enc_reset(void __iomem *base); +u32 mtk_jpeg_enc_get_and_clear_int_status(void __iomem *base); +u32 mtk_jpeg_enc_get_file_size(void __iomem *base); +u32 mtk_jpeg_enc_enum_result(void __iomem *base, u32 irq_status); +void mtk_jpeg_enc_set_img_size(void __iomem *base, u32 width, u32 height); +void mtk_jpeg_enc_set_blk_num(void __iomem *base, u32 enc_format, u32 width, + u32 height); +void mtk_jpeg_enc_set_stride(void __iomem *base, u32 enc_format, u32 width, + u32 height, u32 bytesperline); +void mtk_jpeg_enc_set_src_addr(void __iomem *base, u32 src_addr, + u32 plane_index); +void mtk_jpeg_enc_set_dst_addr(void __iomem *base, u32 dst_addr, + u32 stall_size, u32 init_offset, + u32 offset_mask); +void mtk_jpeg_enc_set_config(void __iomem *base, u32 enc_format, bool exif_en, + u32 quality, u32 restart_interval); +void mtk_jpeg_enc_start(void __iomem *enc_reg_base); + +#endif /* _MTK_JPEG_ENC_HW_H */ -- 2.18.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel