From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hai Li Subject: [PATCH 1/3] drm/msm/dsi: Add DSI PLL clock driver support Date: Fri, 15 May 2015 13:04:04 -0400 Message-ID: <1431709446-31429-2-git-send-email-hali@codeaurora.org> References: <1431709446-31429-1-git-send-email-hali@codeaurora.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1431709446-31429-1-git-send-email-hali@codeaurora.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: dri-devel@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org List-Id: linux-arm-msm@vger.kernel.org RFNJIGJ5dGUgY2xvY2sgYW5kIHBpeGVsIGNsb2NrcyBhcmUgc291cmNlZCBmcm9tIERTSSBQTEwu ClRoaXMgY2hhbmdlIGFkZHMgdGhlIERTSSBQTEwgc291cmNlIGNsb2NrIGRyaXZlciB1bmRlcgpj b21tb24gY2xvY2sgZnJhbWV3b3JrLgoKVGhpcyBjaGFuZ2UgaGFuZGxlcyBEU0kgMjhubSBQTEwg b25seS4KClNpZ25lZC1vZmYtYnk6IEhhaSBMaSA8aGFsaUBjb2RlYXVyb3JhLm9yZz4KU2lnbmVk LW9mZi1ieTogQXJjaGl0IFRhbmVqYSA8YXJjaGl0dEBjb2RlYXVyb3JhLm9yZz4KU2lnbmVkLW9m Zi1ieTogU3RlcGhhbmUgVmlhdSA8c3ZpYXVAY29kZWF1cm9yYS5vcmc+ClNpZ25lZC1vZmYtYnk6 IFdlbnRhbyBYdSA8d2VudGFveEBjb2RlYXVyb3JhLm9yZz4KLS0tCiBkcml2ZXJzL2dwdS9kcm0v bXNtL0tjb25maWcgICAgICAgICAgICAgICAgfCAgIDcgKwogZHJpdmVycy9ncHUvZHJtL21zbS9N YWtlZmlsZSAgICAgICAgICAgICAgIHwgICA1ICsKIGRyaXZlcnMvZ3B1L2RybS9tc20vZHNpL2Rz aS5oICAgICAgICAgICAgICB8ICAgMyArLQogZHJpdmVycy9ncHUvZHJtL21zbS9kc2kvZHNpX2hv c3QuYyAgICAgICAgIHwgIDEwICstCiBkcml2ZXJzL2dwdS9kcm0vbXNtL2RzaS9kc2lfcGh5LmMg ICAgICAgICAgfCAgIDMgKy0KIGRyaXZlcnMvZ3B1L2RybS9tc20vZHNpL3BsbC9kc2lfcGxsLmMg ICAgICB8IDE2NCArKysrKysrKwogZHJpdmVycy9ncHUvZHJtL21zbS9kc2kvcGxsL2RzaV9wbGwu aCAgICAgIHwgIDg5ICsrKysKIGRyaXZlcnMvZ3B1L2RybS9tc20vZHNpL3BsbC9kc2lfcGxsXzI4 bm0uYyB8IDY1MiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKwogOCBmaWxlcyBjaGFuZ2Vk LCA5MjYgaW5zZXJ0aW9ucygrKSwgNyBkZWxldGlvbnMoLSkKIGNyZWF0ZSBtb2RlIDEwMDY0NCBk cml2ZXJzL2dwdS9kcm0vbXNtL2RzaS9wbGwvZHNpX3BsbC5jCiBjcmVhdGUgbW9kZSAxMDA2NDQg ZHJpdmVycy9ncHUvZHJtL21zbS9kc2kvcGxsL2RzaV9wbGwuaAogY3JlYXRlIG1vZGUgMTAwNjQ0 IGRyaXZlcnMvZ3B1L2RybS9tc20vZHNpL3BsbC9kc2lfcGxsXzI4bm0uYwoKZGlmZiAtLWdpdCBh L2RyaXZlcnMvZ3B1L2RybS9tc20vS2NvbmZpZyBiL2RyaXZlcnMvZ3B1L2RybS9tc20vS2NvbmZp ZwppbmRleCAwYTZmNjc2Li4wOGJhOGQwIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vbXNt L0tjb25maWcKKysrIGIvZHJpdmVycy9ncHUvZHJtL21zbS9LY29uZmlnCkBAIC00NiwzICs0Niwx MCBAQCBjb25maWcgRFJNX01TTV9EU0kKIAkgIENob29zZSB0aGlzIG9wdGlvbiBpZiB5b3UgaGF2 ZSBhIG5lZWQgZm9yIE1JUEkgRFNJIGNvbm5lY3RvcgogCSAgc3VwcG9ydC4KIAorY29uZmlnIERS TV9NU01fRFNJX1BMTAorCWJvb2wgIkVuYWJsZSBEU0kgUExMIGRyaXZlciBpbiBNU00gRFJNIgor CWRlcGVuZHMgb24gRFJNX01TTV9EU0kgJiYgQ09NTU9OX0NMSworCWRlZmF1bHQgeQorCWhlbHAK KwkgIENob29zZSB0aGlzIG9wdGlvbiB0byBlbmFibGUgRFNJIFBMTCBkcml2ZXIgd2hpY2ggcHJv dmlkZXMgRFNJCisJICBzb3VyY2UgY2xvY2tzIHVuZGVyIGNvbW1vbiBjbG9jayBmcmFtZXdvcmsu CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vbXNtL01ha2VmaWxlIGIvZHJpdmVycy9ncHUv ZHJtL21zbS9NYWtlZmlsZQppbmRleCBhYjIwODY3Li4xNmE4MWI5IDEwMDY0NAotLS0gYS9kcml2 ZXJzL2dwdS9kcm0vbXNtL01ha2VmaWxlCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9tc20vTWFrZWZp bGUKQEAgLTEsNCArMSw1IEBACiBjY2ZsYWdzLXkgOj0gLUlpbmNsdWRlL2RybSAtSWRyaXZlcnMv Z3B1L2RybS9tc20KK2NjZmxhZ3MtJChDT05GSUdfRFJNX01TTV9EU0lfUExMKSArPSAtSWRyaXZl cnMvZ3B1L2RybS9tc20vZHNpCiAKIG1zbS15IDo9IFwKIAlhZHJlbm8vYWRyZW5vX2RldmljZS5v IFwKQEAgLTUwLDEwICs1MSwxNCBAQCBtc20teSA6PSBcCiAKIG1zbS0kKENPTkZJR19EUk1fTVNN X0ZCREVWKSArPSBtc21fZmJkZXYubwogbXNtLSQoQ09ORklHX0NPTU1PTl9DTEspICs9IG1kcC9t ZHA0L21kcDRfbHZkc19wbGwubworCiBtc20tJChDT05GSUdfRFJNX01TTV9EU0kpICs9IGRzaS9k c2kubyBcCiAJCQlkc2kvZHNpX2hvc3QubyBcCiAJCQlkc2kvZHNpX21hbmFnZXIubyBcCiAJCQlk c2kvZHNpX3BoeS5vIFwKIAkJCW1kcC9tZHA1L21kcDVfY21kX2VuY29kZXIubwogCittc20tJChD T05GSUdfRFJNX01TTV9EU0lfUExMKSArPSBkc2kvcGxsL2RzaV9wbGwubyBcCisJCQkJZHNpL3Bs bC9kc2lfcGxsXzI4bm0ubworCiBvYmotJChDT05GSUdfRFJNX01TTSkJKz0gbXNtLm8KZGlmZiAt LWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9tc20vZHNpL2RzaS5oIGIvZHJpdmVycy9ncHUvZHJtL21z bS9kc2kvZHNpLmgKaW5kZXggMTBmNTRkNC4uMzIxOTY0YSAxMDA2NDQKLS0tIGEvZHJpdmVycy9n cHUvZHJtL21zbS9kc2kvZHNpLmgKKysrIGIvZHJpdmVycy9ncHUvZHJtL21zbS9kc2kvZHNpLmgK QEAgLTEwMyw3ICsxMDMsOCBAQCBpbnQgbXNtX2RzaV9ob3N0X2luaXQoc3RydWN0IG1zbV9kc2kg Km1zbV9kc2kpOwogc3RydWN0IG1zbV9kc2lfcGh5OwogZW51bSBtc21fZHNpX3BoeV90eXBlIHsK IAlNU01fRFNJX1BIWV9VTktOT1dOLAotCU1TTV9EU0lfUEhZXzI4Tk0sCisJTVNNX0RTSV9QSFlf MjhOTV9IUE0sCisJTVNNX0RTSV9QSFlfMjhOTV9MUCwKIAlNU01fRFNJX1BIWV9NQVgKIH07CiBz dHJ1Y3QgbXNtX2RzaV9waHkgKm1zbV9kc2lfcGh5X2luaXQoc3RydWN0IHBsYXRmb3JtX2Rldmlj ZSAqcGRldiwKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9tc20vZHNpL2RzaV9ob3N0LmMg Yi9kcml2ZXJzL2dwdS9kcm0vbXNtL2RzaS9kc2lfaG9zdC5jCmluZGV4IDM2MGI3NjUuLmY3YmE4 OTAgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9tc20vZHNpL2RzaV9ob3N0LmMKKysrIGIv ZHJpdmVycy9ncHUvZHJtL21zbS9kc2kvZHNpX2hvc3QuYwpAQCAtNjQsNyArNjQsNyBAQCBzdGF0 aWMgY29uc3Qgc3RydWN0IGRzaV9jb25maWcgZHNpX2NmZ3NbXSA9IHsKIAkJLm1ham9yID0gTVNN X0RTSV9WRVJfTUFKT1JfNkcsCiAJCS5taW5vciA9IE1TTV9EU0lfNkdfVkVSX01JTk9SX1YxXzAs CiAJCS5pb19vZmZzZXQgPSBEU0lfNkdfUkVHX1NISUZULAotCQkucGh5X3R5cGUgPSBNU01fRFNJ X1BIWV8yOE5NLAorCQkucGh5X3R5cGUgPSBNU01fRFNJX1BIWV8yOE5NX0hQTSwKIAkJLnJlZ19j ZmcgPSB7CiAJCQkubnVtID0gNCwKIAkJCS5yZWdzID0gewpAQCAtNzksNyArNzksNyBAQCBzdGF0 aWMgY29uc3Qgc3RydWN0IGRzaV9jb25maWcgZHNpX2NmZ3NbXSA9IHsKIAkJLm1ham9yID0gTVNN X0RTSV9WRVJfTUFKT1JfNkcsCiAJCS5taW5vciA9IE1TTV9EU0lfNkdfVkVSX01JTk9SX1YxXzEs CiAJCS5pb19vZmZzZXQgPSBEU0lfNkdfUkVHX1NISUZULAotCQkucGh5X3R5cGUgPSBNU01fRFNJ X1BIWV8yOE5NLAorCQkucGh5X3R5cGUgPSBNU01fRFNJX1BIWV8yOE5NX0hQTSwKIAkJLnJlZ19j ZmcgPSB7CiAJCQkubnVtID0gNCwKIAkJCS5yZWdzID0gewpAQCAtOTQsNyArOTQsNyBAQCBzdGF0 aWMgY29uc3Qgc3RydWN0IGRzaV9jb25maWcgZHNpX2NmZ3NbXSA9IHsKIAkJLm1ham9yID0gTVNN X0RTSV9WRVJfTUFKT1JfNkcsCiAJCS5taW5vciA9IE1TTV9EU0lfNkdfVkVSX01JTk9SX1YxXzFf MSwKIAkJLmlvX29mZnNldCA9IERTSV82R19SRUdfU0hJRlQsCi0JCS5waHlfdHlwZSA9IE1TTV9E U0lfUEhZXzI4Tk0sCisJCS5waHlfdHlwZSA9IE1TTV9EU0lfUEhZXzI4Tk1fSFBNLAogCQkucmVn X2NmZyA9IHsKIAkJCS5udW0gPSA0LAogCQkJLnJlZ3MgPSB7CkBAIC0xMDksNyArMTA5LDcgQEAg c3RhdGljIGNvbnN0IHN0cnVjdCBkc2lfY29uZmlnIGRzaV9jZmdzW10gPSB7CiAJCS5tYWpvciA9 IE1TTV9EU0lfVkVSX01BSk9SXzZHLAogCQkubWlub3IgPSBNU01fRFNJXzZHX1ZFUl9NSU5PUl9W MV8yLAogCQkuaW9fb2Zmc2V0ID0gRFNJXzZHX1JFR19TSElGVCwKLQkJLnBoeV90eXBlID0gTVNN X0RTSV9QSFlfMjhOTSwKKwkJLnBoeV90eXBlID0gTVNNX0RTSV9QSFlfMjhOTV9IUE0sCiAJCS5y ZWdfY2ZnID0gewogCQkJLm51bSA9IDQsCiAJCQkucmVncyA9IHsKQEAgLTEyNCw3ICsxMjQsNyBA QCBzdGF0aWMgY29uc3Qgc3RydWN0IGRzaV9jb25maWcgZHNpX2NmZ3NbXSA9IHsKIAkJLm1ham9y ID0gTVNNX0RTSV9WRVJfTUFKT1JfNkcsCiAJCS5taW5vciA9IE1TTV9EU0lfNkdfVkVSX01JTk9S X1YxXzNfMSwKIAkJLmlvX29mZnNldCA9IERTSV82R19SRUdfU0hJRlQsCi0JCS5waHlfdHlwZSA9 IE1TTV9EU0lfUEhZXzI4Tk0sCisJCS5waHlfdHlwZSA9IE1TTV9EU0lfUEhZXzI4Tk1fTFAsCiAJ CS5yZWdfY2ZnID0gewogCQkJLm51bSA9IDQsCiAJCQkucmVncyA9IHsKZGlmZiAtLWdpdCBhL2Ry aXZlcnMvZ3B1L2RybS9tc20vZHNpL2RzaV9waHkuYyBiL2RyaXZlcnMvZ3B1L2RybS9tc20vZHNp L2RzaV9waHkuYwppbmRleCBmMGNlYTg5Li5mYzExNDc0IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dw dS9kcm0vbXNtL2RzaS9kc2lfcGh5LmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL21zbS9kc2kvZHNp X3BoeS5jCkBAIC0zMTEsNyArMzExLDggQEAgc3RydWN0IG1zbV9kc2lfcGh5ICptc21fZHNpX3Bo eV9pbml0KHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYsCiAJfQogCiAJc3dpdGNoICh0eXBl KSB7Ci0JY2FzZSBNU01fRFNJX1BIWV8yOE5NOgorCWNhc2UgTVNNX0RTSV9QSFlfMjhOTV9IUE06 CisJY2FzZSBNU01fRFNJX1BIWV8yOE5NX0xQOgogCQlkc2lfcGh5X2Z1bmNfaW5pdCgyOG5tKTsK IAkJYnJlYWs7CiAJZGVmYXVsdDoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9tc20vZHNp L3BsbC9kc2lfcGxsLmMgYi9kcml2ZXJzL2dwdS9kcm0vbXNtL2RzaS9wbGwvZHNpX3BsbC5jCm5l dyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwOTM3NmYKLS0tIC9kZXYvbnVsbAor KysgYi9kcml2ZXJzL2dwdS9kcm0vbXNtL2RzaS9wbGwvZHNpX3BsbC5jCkBAIC0wLDAgKzEsMTY0 IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEyLTIwMTUsIFRoZSBMaW51eCBGb3VuZGF0aW9u LiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3 YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CisgKiBpdCB1bmRlciB0 aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhbmQK KyAqIG9ubHkgdmVyc2lvbiAyIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3Vu ZGF0aW9uLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0 aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAorICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRo b3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKKyAqIE1FUkNIQU5UQUJJTElUWSBvciBG SVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKKyAqIEdOVSBHZW5lcmFs IFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworI2luY2x1ZGUgImRzaV9w bGwuaCIKKworc3RhdGljIGludCBkc2lfcGxsX2VuYWJsZShzdHJ1Y3QgbXNtX2RzaV9wbGwgKnBs bCkKK3sKKwlpbnQgaSwgcmV0ID0gMDsKKworCS8qCisJICogQ2VydGFpbiBQTExzIGRvIG5vdCBh bGxvdyBWQ08gcmF0ZSB1cGRhdGUgd2hlbiBpdCBpcyBvbi4KKwkgKiBLZWVwIHRyYWNrIG9mIHRo ZWlyIHN0YXR1cyB0byB0dXJuIG9uL29mZiBhZnRlciBzZXQgcmF0ZSBzdWNjZXNzLgorCSAqLwor CWlmICh1bmxpa2VseShwbGwtPnBsbF9vbikpCisJCXJldHVybiAwOworCisJLyogVHJ5IGFsbCBl bmFibGUgc2VxdWVuY2VzIHVudGlsIG9uZSBzdWNjZWVkcyAqLworCWZvciAoaSA9IDA7IGkgPCBw bGwtPmVuX3NlcV9jbnQ7IGkrKykgeworCQlyZXQgPSBwbGwtPmVuYWJsZV9zZXFzW2ldKHBsbCk7 CisJCURCRygiRFNJIFBMTCAlcyBhZnRlciBzZXF1ZW5jZSAjJWQiLAorCQkJcmV0ID8gInVubG9j a2VkIiA6ICJsb2NrZWQiLCBpICsgMSk7CisJCWlmICghcmV0KQorCQkJYnJlYWs7CisJfQorCisJ aWYgKHJldCkgeworCQlEUk1fRVJST1IoIkRTSSBQTEwgZmFpbGVkIHRvIGxvY2tcbiIpOworCQly ZXR1cm4gcmV0OworCX0KKworCXBsbC0+cGxsX29uID0gdHJ1ZTsKKworCXJldHVybiAwOworfQor CitzdGF0aWMgdm9pZCBkc2lfcGxsX2Rpc2FibGUoc3RydWN0IG1zbV9kc2lfcGxsICpwbGwpCit7 CisJaWYgKHVubGlrZWx5KCFwbGwtPnBsbF9vbikpCisJCXJldHVybjsKKworCXBsbC0+ZGlzYWJs ZV9zZXEocGxsKTsKKworCXBsbC0+cGxsX29uID0gZmFsc2U7Cit9CisKKy8qCisgKiBEU0kgUExM IEhlbHBlciBmdW5jdGlvbnMKKyAqLworbG9uZyBtc21fZHNpX3BsbF9oZWxwZXJfY2xrX3JvdW5k X3JhdGUoc3RydWN0IGNsa19odyAqaHcsCisJCXVuc2lnbmVkIGxvbmcgcmF0ZSwgdW5zaWduZWQg bG9uZyAqcGFyZW50X3JhdGUpCit7CisJc3RydWN0IG1zbV9kc2lfcGxsICpwbGwgPSBod19jbGtf dG9fcGxsKGh3KTsKKworCWlmICAgICAgKHJhdGUgPCBwbGwtPm1pbl9yYXRlKQorCQlyZXR1cm4g IHBsbC0+bWluX3JhdGU7CisJZWxzZSBpZiAocmF0ZSA+IHBsbC0+bWF4X3JhdGUpCisJCXJldHVy biAgcGxsLT5tYXhfcmF0ZTsKKwllbHNlCisJCXJldHVybiByYXRlOworfQorCitpbnQgbXNtX2Rz aV9wbGxfaGVscGVyX2Nsa19wcmVwYXJlKHN0cnVjdCBjbGtfaHcgKmh3KQoreworCXN0cnVjdCBt c21fZHNpX3BsbCAqcGxsID0gaHdfY2xrX3RvX3BsbChodyk7CisJaW50IHJldDsKKworCS8qCisJ ICogQ2VydGFpbiBQTExzIG5lZWQgdG8gdXBkYXRlIHRoZSBzYW1lIFZDTyByYXRlIGFuZCByZWdp c3RlcnMKKwkgKiBhZnRlciByZXN1bWUgaW4gc3VzcGVuZC9yZXN1bWUgc2NlbmFyaW8uCisJICov CisJaWYgKHBsbC0+cmVzdG9yZV9zdGF0ZSkgeworCQlyZXQgPSBwbGwtPnJlc3RvcmVfc3RhdGUo cGxsKTsKKwkJaWYgKHJldCkKKwkJCWdvdG8gZXJyb3I7CisJfQorCisJcmV0ID0gZHNpX3BsbF9l bmFibGUocGxsKTsKKworZXJyb3I6CisJcmV0dXJuIHJldDsKK30KKwordm9pZCBtc21fZHNpX3Bs bF9oZWxwZXJfY2xrX3VucHJlcGFyZShzdHJ1Y3QgY2xrX2h3ICpodykKK3sKKwlzdHJ1Y3QgbXNt X2RzaV9wbGwgKnBsbCA9IGh3X2Nsa190b19wbGwoaHcpOworCisJaWYgKHBsbC0+c2F2ZV9zdGF0 ZSkKKwkJcGxsLT5zYXZlX3N0YXRlKHBsbCk7CisKKwlkc2lfcGxsX2Rpc2FibGUocGxsKTsKK30K Kwordm9pZCBtc21fZHNpX3BsbF9oZWxwZXJfdW5yZWdpc3Rlcl9jbGtzKHN0cnVjdCBwbGF0Zm9y bV9kZXZpY2UgKnBkZXYsCisJCQkJCXN0cnVjdCBjbGsgKipjbGtzLCB1MzIgbnVtX2Nsa3MpCit7 CisJb2ZfY2xrX2RlbF9wcm92aWRlcihwZGV2LT5kZXYub2Zfbm9kZSk7CisKKwlpZiAoIW51bV9j bGtzIHx8ICFjbGtzKQorCQlyZXR1cm47CisKKwlkbyB7CisJCWNsa191bnJlZ2lzdGVyKGNsa3Nb LS1udW1fY2xrc10pOworCQljbGtzW251bV9jbGtzXSA9IE5VTEw7CisJfSB3aGlsZSAobnVtX2Ns a3MpOworfQorCisvKgorICogRFNJIFBMTCBBUEkKKyAqLworaW50IG1zbV9kc2lfcGxsX2dldF9j bGtfcHJvdmlkZXIoc3RydWN0IG1zbV9kc2lfcGxsICpwbGwsCisJc3RydWN0IGNsayAqKmJ5dGVf Y2xrX3Byb3ZpZGVyLCBzdHJ1Y3QgY2xrICoqcGl4ZWxfY2xrX3Byb3ZpZGVyKQoreworCWlmIChw bGwtPmdldF9wcm92aWRlcikKKwkJcmV0dXJuIHBsbC0+Z2V0X3Byb3ZpZGVyKHBsbCwKKwkJCQkJ Ynl0ZV9jbGtfcHJvdmlkZXIsCisJCQkJCXBpeGVsX2Nsa19wcm92aWRlcik7CisKKwlyZXR1cm4g LUVJTlZBTDsKK30KKwordm9pZCBtc21fZHNpX3BsbF9kZXN0cm95KHN0cnVjdCBtc21fZHNpX3Bs bCAqcGxsKQoreworCWlmIChwbGwtPmRlc3Ryb3kpCisJCXBsbC0+ZGVzdHJveShwbGwpOworfQor CitzdHJ1Y3QgbXNtX2RzaV9wbGwgKm1zbV9kc2lfcGxsX2luaXQoc3RydWN0IHBsYXRmb3JtX2Rl dmljZSAqcGRldiwKKwkJCWVudW0gbXNtX2RzaV9waHlfdHlwZSB0eXBlLCBpbnQgaWQpCit7CisJ c3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKKwlzdHJ1Y3QgbXNtX2RzaV9wbGwgKnBs bDsKKworCXN3aXRjaCAodHlwZSkgeworCWNhc2UgTVNNX0RTSV9QSFlfMjhOTV9IUE06CisJY2Fz ZSBNU01fRFNJX1BIWV8yOE5NX0xQOgorCQlwbGwgPSBtc21fZHNpX3BsbF8yOG5tX2luaXQocGRl diwgdHlwZSwgaWQpOworCQlicmVhazsKKwlkZWZhdWx0OgorCQlwbGwgPSBFUlJfUFRSKC1FTlhJ Tyk7CisJCWJyZWFrOworCX0KKworCWlmIChJU19FUlIocGxsKSkgeworCQlkZXZfZXJyKGRldiwg IiVzOiBmYWlsZWQgdG8gaW5pdCBEU0kgUExMXG4iLCBfX2Z1bmNfXyk7CisJCXJldHVybiBOVUxM OworCX0KKworCXBsbC0+dHlwZSA9IHR5cGU7CisKKwlEQkcoIkRTSTolZCBQTEwgcmVnaXN0ZXJl ZCIsIGlkKTsKKworCXJldHVybiBwbGw7Cit9CisKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2Ry bS9tc20vZHNpL3BsbC9kc2lfcGxsLmggYi9kcml2ZXJzL2dwdS9kcm0vbXNtL2RzaS9wbGwvZHNp X3BsbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVhM2JiMjQxCi0tLSAv ZGV2L251bGwKKysrIGIvZHJpdmVycy9ncHUvZHJtL21zbS9kc2kvcGxsL2RzaV9wbGwuaApAQCAt MCwwICsxLDg5IEBACisvKgorICogQ29weXJpZ2h0IChjKSAyMDEyLTIwMTUsIFRoZSBMaW51eCBG b3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBm cmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CisgKiBp dCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNp b24gMiBhbmQKKyAqIG9ubHkgdmVyc2lvbiAyIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0 d2FyZSBGb3VuZGF0aW9uLgorICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0 aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAorICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJB TlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKKyAqIE1FUkNIQU5UQUJJ TElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKKyAqIEdO VSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCisgKi8KKworI2lmbmRl ZiBfX0RTSV9QTExfSF9fCisjZGVmaW5lIF9fRFNJX1BMTF9IX18KKworI2luY2x1ZGUgPGxpbnV4 L2Nsay5oPgorI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92aWRlci5oPgorCisjaW5jbHVkZSAiZHNp LmgiCisKKyNkZWZpbmUgTlVNX0RTSV9DTE9DS1NfTUFYCTYKKyNkZWZpbmUgTUFYX0RTSV9QTExf RU5fU0VRUwkxMAorCitzdHJ1Y3QgbXNtX2RzaV9wbGwgeworCWVudW0gbXNtX2RzaV9waHlfdHlw ZSB0eXBlOworCisJc3RydWN0IGNsa19odwljbGtfaHc7CisJYm9vbAkJcGxsX29uOworCisJdW5z aWduZWQgbG9uZwltaW5fcmF0ZTsKKwl1bnNpZ25lZCBsb25nCW1heF9yYXRlOworCXUzMgkJZW5f c2VxX2NudDsKKworCWludCAoKmVuYWJsZV9zZXFzW01BWF9EU0lfUExMX0VOX1NFUVNdKShzdHJ1 Y3QgbXNtX2RzaV9wbGwgKnBsbCk7CisJdm9pZCAoKmRpc2FibGVfc2VxKShzdHJ1Y3QgbXNtX2Rz aV9wbGwgKnBsbCk7CisJaW50ICgqZ2V0X3Byb3ZpZGVyKShzdHJ1Y3QgbXNtX2RzaV9wbGwgKnBs bCwKKwkJCXN0cnVjdCBjbGsgKipieXRlX2Nsa19wcm92aWRlciwKKwkJCXN0cnVjdCBjbGsgKipw aXhlbF9jbGtfcHJvdmlkZXIpOworCXZvaWQgKCpkZXN0cm95KShzdHJ1Y3QgbXNtX2RzaV9wbGwg KnBsbCk7CisJdm9pZCAoKnNhdmVfc3RhdGUpKHN0cnVjdCBtc21fZHNpX3BsbCAqcGxsKTsKKwlp bnQgKCpyZXN0b3JlX3N0YXRlKShzdHJ1Y3QgbXNtX2RzaV9wbGwgKnBsbCk7Cit9OworCisjZGVm aW5lIGh3X2Nsa190b19wbGwoeCkgY29udGFpbmVyX29mKHgsIHN0cnVjdCBtc21fZHNpX3BsbCwg Y2xrX2h3KQorCitzdGF0aWMgaW5saW5lIHZvaWQgcGxsX3dyaXRlKHZvaWQgX19pb21lbSAqcmVn LCB1MzIgZGF0YSkKK3sKKwltc21fd3JpdGVsKGRhdGEsIHJlZyk7Cit9CisKK3N0YXRpYyBpbmxp bmUgdTMyIHBsbF9yZWFkKGNvbnN0IHZvaWQgX19pb21lbSAqcmVnKQoreworCXJldHVybiBtc21f cmVhZGwocmVnKTsKK30KKworc3RhdGljIGlubGluZSB2b2lkIHBsbF93cml0ZV91ZGVsYXkodm9p ZCBfX2lvbWVtICpyZWcsIHUzMiBkYXRhLCB1MzIgZGVsYXlfdXMpCit7CisJcGxsX3dyaXRlKHJl ZywgZGF0YSk7CisJdWRlbGF5KGRlbGF5X3VzKTsKK30KKworc3RhdGljIGlubGluZSB2b2lkIHBs bF93cml0ZV9uZGVsYXkodm9pZCBfX2lvbWVtICpyZWcsIHUzMiBkYXRhLCB1MzIgZGVsYXlfbnMp Cit7CisJcGxsX3dyaXRlKChyZWcpLCBkYXRhKTsKKwluZGVsYXkoZGVsYXlfbnMpOworfQorCisv KgorICogRFNJIFBMTCBIZWxwZXIgZnVuY3Rpb25zCisgKi8KKworLyogY2xvY2sgY2FsbGJhY2tz ICovCitsb25nIG1zbV9kc2lfcGxsX2hlbHBlcl9jbGtfcm91bmRfcmF0ZShzdHJ1Y3QgY2xrX2h3 ICpodywKKwkJdW5zaWduZWQgbG9uZyByYXRlLCB1bnNpZ25lZCBsb25nICpwYXJlbnRfcmF0ZSk7 CitpbnQgbXNtX2RzaV9wbGxfaGVscGVyX2Nsa19wcmVwYXJlKHN0cnVjdCBjbGtfaHcgKmh3KTsK K3ZvaWQgbXNtX2RzaV9wbGxfaGVscGVyX2Nsa191bnByZXBhcmUoc3RydWN0IGNsa19odyAqaHcp OworLyogbWlzYyAqLwordm9pZCBtc21fZHNpX3BsbF9oZWxwZXJfdW5yZWdpc3Rlcl9jbGtzKHN0 cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYsCisJCQkJCXN0cnVjdCBjbGsgKipjbGtzLCB1MzIg bnVtX2Nsa3MpOworCisvKgorICogSW5pdGlhbGl6YXRpb24gZm9yIEVhY2ggUExMIFR5cGUKKyAq Lworc3RydWN0IG1zbV9kc2lfcGxsICptc21fZHNpX3BsbF8yOG5tX2luaXQoc3RydWN0IHBsYXRm b3JtX2RldmljZSAqcGRldiwKKwkJCQkJZW51bSBtc21fZHNpX3BoeV90eXBlIHR5cGUsIGludCBp ZCk7CisKKyNlbmRpZiAvKiBfX0RTSV9QTExfSF9fICovCisKZGlmZiAtLWdpdCBhL2RyaXZlcnMv Z3B1L2RybS9tc20vZHNpL3BsbC9kc2lfcGxsXzI4bm0uYyBiL2RyaXZlcnMvZ3B1L2RybS9tc20v ZHNpL3BsbC9kc2lfcGxsXzI4bm0uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAw Li5lYjhhYzMwCi0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9ncHUvZHJtL21zbS9kc2kvcGxs L2RzaV9wbGxfMjhubS5jCkBAIC0wLDAgKzEsNjUyIEBACisvKgorICogQ29weXJpZ2h0IChjKSAy MDEyLTIwMTUsIFRoZSBMaW51eCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoK KyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBp dCBhbmQvb3IgbW9kaWZ5CisgKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFs IFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhbmQKKyAqIG9ubHkgdmVyc2lvbiAyIGFzIHB1Ymxp c2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgorICoKKyAqIFRoaXMgcHJvZ3Jh bSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAorICog YnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFu dHkgb2YKKyAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVS UE9TRS4gIFNlZSB0aGUKKyAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRl dGFpbHMuCisgKi8KKworI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgorI2luY2x1ZGUgPGxpbnV4L2Ns ay1wcm92aWRlci5oPgorCisjaW5jbHVkZSAiZHNpX3BsbC5oIgorI2luY2x1ZGUgImRzaS54bWwu aCIKKworLyoKKyAqIERTSSBQTEwgMjhubSAtIGNsb2NrIGRpYWdyYW0gKGVnOiBEU0kwKToKKyAq CisgKiAgICAgICAgIGRzaTBhbmFsb2dfcG9zdGRpdl9jbGsKKyAqICAgICAgICAgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgZHNpMGluZGlyZWN0X3BhdGhfZGl2Ml9jbGsKKyAqICAgICAg ICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwKKyAqICAgICAgICAgICAgICAgICAg ICstLS0tLS0rICB8ICArLS0tLSsgIHwgIHxcICAgZHNpMGJ5dGVfbXV4CisgKiAgZHNpMHZjb19j bGsgLS1vLS18IERJVjEgfC0tby0tfCAvMiB8LS1vLS18IFwgICB8CisgKiAgICAgICAgICAgICAg ICB8ICArLS0tLS0tKyAgICAgKy0tLS0rICAgICB8IG18ICB8ICArLS0tLSsKKyAqICAgICAgICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgIHwgdXwtLW8tLXwgLzQgfC0tIGRzaTBw bGxieXRlCisgKiAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICB8IHh8 ICAgICArLS0tLSsKKyAqICAgICAgICAgICAgICAgIG8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LXwgLworICogICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgfC8KKyAq ICAgICAgICAgICAgICAgIHwgICAgICAgICAgKy0tLS0tLSsKKyAqICAgICAgICAgICAgICAgIG8t LS0tLS0tLS0tfCBESVYzIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGRzaTBwbGwKKyAqICAg ICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tLSsKKyAqLworCisjZGVmaW5lIFBPTExfTUFY X1JFQURTCQkJMTAKKyNkZWZpbmUgUE9MTF9USU1FT1VUX1VTCQk1MAorCisjZGVmaW5lIE5VTV9Q Uk9WSURFRF9DTEtTCQkyCisKKyNkZWZpbmUgVkNPX1JFRl9DTEtfUkFURQkJMTkyMDAwMDAKKyNk ZWZpbmUgVkNPX01JTl9SQVRFCQkJMzUwMDAwMDAwCisjZGVmaW5lIFZDT19NQVhfUkFURQkJCTc1 MDAwMDAwMAorCisjZGVmaW5lIERTSV9CWVRFX1BMTF9DTEsJCTAKKyNkZWZpbmUgRFNJX1BJWEVM X1BMTF9DTEsJCTEKKworI2RlZmluZSBMUEZSX0xVVF9TSVpFCQkJMTAKK3N0cnVjdCBscGZyX2Nm ZyB7CisJdW5zaWduZWQgbG9uZyB2Y29fcmF0ZTsKKwl1MzIgcmVzaXN0YW5jZTsKK307CisKKy8q IExvb3AgZmlsdGVyIHJlc2lzdGFuY2U6ICovCitzdGF0aWMgY29uc3Qgc3RydWN0IGxwZnJfY2Zn IGxwZnJfbHV0W0xQRlJfTFVUX1NJWkVdID0geworCXsgNDc5NTAwMDAwLCAgOCB9LAorCXsgNDgw MDAwMDAwLCAxMSB9LAorCXsgNTc1NTAwMDAwLCAgOCB9LAorCXsgNTc2MDAwMDAwLCAxMiB9LAor CXsgNjEwNTAwMDAwLCAgOCB9LAorCXsgNjU5NTAwMDAwLCAgOSB9LAorCXsgNjcxNTAwMDAwLCAx MCB9LAorCXsgNjcyMDAwMDAwLCAxNCB9LAorCXsgNzA4NTAwMDAwLCAxMCB9LAorCXsgNzUwMDAw MDAwLCAxMSB9LAorfTsKKworc3RydWN0IHBsbF8yOG5tX2NhY2hlZF9zdGF0ZSB7CisJdW5zaWdu ZWQgbG9uZyB2Y29fcmF0ZTsKKwl1OCBwb3N0ZGl2MzsKKwl1OCBwb3N0ZGl2MTsKKwl1OCBieXRl X211eDsKK307CisKK3N0cnVjdCBkc2lfcGxsXzI4bm0geworCXN0cnVjdCBtc21fZHNpX3BsbCBi YXNlOworCisJaW50IGlkOworCXN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXY7CisJdm9pZCBf X2lvbWVtICptbWlvOworCisJaW50IHZjb19kZWxheTsKKworCS8qIHByaXZhdGUgY2xvY2tzOiAq LworCXN0cnVjdCBjbGsgKmNsa3NbTlVNX0RTSV9DTE9DS1NfTUFYXTsKKwl1MzIgbnVtX2Nsa3M7 CisKKwkvKiBjbG9jay1wcm92aWRlcjogKi8KKwlzdHJ1Y3QgY2xrICpwcm92aWRlZF9jbGtzW05V TV9QUk9WSURFRF9DTEtTXTsKKwlzdHJ1Y3QgY2xrX29uZWNlbGxfZGF0YSBjbGtfZGF0YTsKKwor CXN0cnVjdCBwbGxfMjhubV9jYWNoZWRfc3RhdGUgY2FjaGVkX3N0YXRlOworfTsKKworI2RlZmlu ZSB0b19wbGxfMjhubSh4KQljb250YWluZXJfb2YoeCwgc3RydWN0IGRzaV9wbGxfMjhubSwgYmFz ZSkKKworc3RhdGljIGJvb2wgcGxsXzI4bm1fcG9sbF9mb3JfcmVhZHkoc3RydWN0IGRzaV9wbGxf MjhubSAqcGxsXzI4bm0sCisJCQkJdTMyIG5iX3RyaWVzLCB1MzIgdGltZW91dF91cykKK3sKKwli b29sIHBsbF9sb2NrZWQgPSBmYWxzZTsKKwl1MzIgdmFsOworCisJd2hpbGUgKG5iX3RyaWVzLS0p IHsKKwkJdmFsID0gcGxsX3JlYWQocGxsXzI4bm0tPm1taW8gKyBSRUdfRFNJXzI4bm1fUEhZX1BM TF9TVEFUVVMpOworCQlwbGxfbG9ja2VkID0gISEodmFsICYgRFNJXzI4bm1fUEhZX1BMTF9TVEFU VVNfUExMX1JEWSk7CisKKwkJaWYgKHBsbF9sb2NrZWQpCisJCQlicmVhazsKKworCQl1ZGVsYXko dGltZW91dF91cyk7CisJfQorCURCRygiRFNJIFBMTCBpcyAlc2xvY2tlZCIsIHBsbF9sb2NrZWQg PyAiIiA6ICIqbm90KiAiKTsKKworCXJldHVybiBwbGxfbG9ja2VkOworfQorCitzdGF0aWMgdm9p ZCBwbGxfMjhubV9zb2Z0d2FyZV9yZXNldChzdHJ1Y3QgZHNpX3BsbF8yOG5tICpwbGxfMjhubSkK K3sKKwl2b2lkIF9faW9tZW0gKmJhc2UgPSBwbGxfMjhubS0+bW1pbzsKKworCS8qCisJICogQWRk IEhXIHJlY29tbWVuZGVkIGRlbGF5cyBhZnRlciB0b2dnbGluZyB0aGUgc29mdHdhcmUKKwkgKiBy ZXNldCBiaXQgb2ZmIGFuZCBiYWNrIG9uLgorCSAqLworCXBsbF93cml0ZV91ZGVsYXkoYmFzZSAr IFJFR19EU0lfMjhubV9QSFlfUExMX1RFU1RfQ0ZHLAorCQkJRFNJXzI4bm1fUEhZX1BMTF9URVNU X0NGR19QTExfU1dfUkVTRVQsIDEpOworCXBsbF93cml0ZV91ZGVsYXkoYmFzZSArIFJFR19EU0lf MjhubV9QSFlfUExMX1RFU1RfQ0ZHLCAweDAwLCAxKTsKK30KKworLyoKKyAqIENsb2NrIENhbGxi YWNrcworICovCitzdGF0aWMgaW50IGRzaV9wbGxfMjhubV9jbGtfc2V0X3JhdGUoc3RydWN0IGNs a19odyAqaHcsIHVuc2lnbmVkIGxvbmcgcmF0ZSwKKwkJdW5zaWduZWQgbG9uZyBwYXJlbnRfcmF0 ZSkKK3sKKwlzdHJ1Y3QgbXNtX2RzaV9wbGwgKnBsbCA9IGh3X2Nsa190b19wbGwoaHcpOworCXN0 cnVjdCBkc2lfcGxsXzI4bm0gKnBsbF8yOG5tID0gdG9fcGxsXzI4bm0ocGxsKTsKKwlzdHJ1Y3Qg ZGV2aWNlICpkZXYgPSAmcGxsXzI4bm0tPnBkZXYtPmRldjsKKwl2b2lkIF9faW9tZW0gKmJhc2Ug PSBwbGxfMjhubS0+bW1pbzsKKwl1bnNpZ25lZCBsb25nIGRpdl9mYngxMDAwLCBnZW5fdmNvX2Ns azsKKwl1MzIgcmVmY2xrX2NmZywgZnJhY19uX21vZGUsIGZyYWNfbl92YWx1ZTsKKwl1MzIgc2Rt X2NmZzAsIHNkbV9jZmcxLCBzZG1fY2ZnMiwgc2RtX2NmZzM7CisJdTMyIGNhbF9jZmcxMCwgY2Fs X2NmZzExOworCXUzMiByZW07CisJaW50IGk7CisKKwlWRVJCKCJyYXRlPSVsdSwgcGFyZW50J3M9 JWx1IiwgcmF0ZSwgcGFyZW50X3JhdGUpOworCisJLyogRm9yY2UgcG9zdGRpdjIgdG8gYmUgZGl2 LTQgKi8KKwlwbGxfd3JpdGUoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX1BPU1RESVYyX0NG RywgMyk7CisKKwkvKiBDb25maWd1cmUgdGhlIExvb3AgZmlsdGVyIHJlc2lzdGFuY2UgKi8KKwlm b3IgKGkgPSAwOyBpIDwgTFBGUl9MVVRfU0laRTsgaSsrKQorCQlpZiAocmF0ZSA8PSBscGZyX2x1 dFtpXS52Y29fcmF0ZSkKKwkJCWJyZWFrOworCWlmIChpID09IExQRlJfTFVUX1NJWkUpIHsKKwkJ ZGV2X2VycihkZXYsICJ1bmFibGUgdG8gZ2V0IGxvb3AgZmlsdGVyIHJlc2lzdGFuY2UuIHZjbz0l bHVcbiIsCisJCQkJcmF0ZSk7CisJCXJldHVybiAtRUlOVkFMOworCX0KKwlwbGxfd3JpdGUoYmFz ZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0xQRlJfQ0ZHLCBscGZyX2x1dFtpXS5yZXNpc3RhbmNl KTsKKworCS8qIExvb3AgZmlsdGVyIGNhcGFjaXRhbmNlIHZhbHVlcyA6IGMxIGFuZCBjMiAqLwor CXBsbF93cml0ZShiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfTFBGQzFfQ0ZHLCAweDcwKTsK KwlwbGxfd3JpdGUoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0xQRkMyX0NGRywgMHgxNSk7 CisKKwlyZW0gPSByYXRlICUgVkNPX1JFRl9DTEtfUkFURTsKKwlpZiAocmVtKSB7CisJCXJlZmNs a19jZmcgPSBEU0lfMjhubV9QSFlfUExMX1JFRkNMS19DRkdfREJMUjsKKwkJZnJhY19uX21vZGUg PSAxOworCQlkaXZfZmJ4MTAwMCA9IHJhdGUgLyAoVkNPX1JFRl9DTEtfUkFURSAvIDUwMCk7CisJ CWdlbl92Y29fY2xrID0gZGl2X2ZieDEwMDAgKiAoVkNPX1JFRl9DTEtfUkFURSAvIDUwMCk7CisJ fSBlbHNlIHsKKwkJcmVmY2xrX2NmZyA9IDB4MDsKKwkJZnJhY19uX21vZGUgPSAwOworCQlkaXZf ZmJ4MTAwMCA9IHJhdGUgLyAoVkNPX1JFRl9DTEtfUkFURSAvIDEwMDApOworCQlnZW5fdmNvX2Ns ayA9IGRpdl9mYngxMDAwICogKFZDT19SRUZfQ0xLX1JBVEUgLyAxMDAwKTsKKwl9CisKKwlEQkco InJlZmNsa19jZmcgPSAlZCIsIHJlZmNsa19jZmcpOworCisJcmVtID0gZGl2X2ZieDEwMDAgJSAx MDAwOworCWZyYWNfbl92YWx1ZSA9IChyZW0gPDwgMTYpIC8gMTAwMDsKKworCURCRygiZGl2X2Zi ID0gJWx1IiwgZGl2X2ZieDEwMDApOworCURCRygiZnJhY19uX3ZhbHVlID0gJWQiLCBmcmFjX25f dmFsdWUpOworCisJREJHKCJHZW5lcmF0ZWQgVkNPIENsb2NrOiAlbHUiLCBnZW5fdmNvX2Nsayk7 CisJcmVtID0gMDsKKwlzZG1fY2ZnMSA9IHBsbF9yZWFkKGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZ X1BMTF9TRE1fQ0ZHMSk7CisJc2RtX2NmZzEgJj0gfkRTSV8yOG5tX1BIWV9QTExfU0RNX0NGRzFf RENfT0ZGU0VUX19NQVNLOworCWlmIChmcmFjX25fbW9kZSkgeworCQlzZG1fY2ZnMCA9IDB4MDsK KwkJc2RtX2NmZzAgfD0gRFNJXzI4bm1fUEhZX1BMTF9TRE1fQ0ZHMF9CWVBfRElWKDApOworCQlz ZG1fY2ZnMSB8PSBEU0lfMjhubV9QSFlfUExMX1NETV9DRkcxX0RDX09GRlNFVCgKKwkJCQkodTMy KSgoKGRpdl9mYngxMDAwIC8gMTAwMCkgJiAweDNmKSAtIDEpKTsKKwkJc2RtX2NmZzMgPSBmcmFj X25fdmFsdWUgPj4gODsKKwkJc2RtX2NmZzIgPSBmcmFjX25fdmFsdWUgJiAweGZmOworCX0gZWxz ZSB7CisJCXNkbV9jZmcwID0gRFNJXzI4bm1fUEhZX1BMTF9TRE1fQ0ZHMF9CWVA7CisJCXNkbV9j ZmcwIHw9IERTSV8yOG5tX1BIWV9QTExfU0RNX0NGRzBfQllQX0RJVigKKwkJCQkodTMyKSgoKGRp dl9mYngxMDAwIC8gMTAwMCkgJiAweDNmKSAtIDEpKTsKKwkJc2RtX2NmZzEgfD0gRFNJXzI4bm1f UEhZX1BMTF9TRE1fQ0ZHMV9EQ19PRkZTRVQoMCk7CisJCXNkbV9jZmcyID0gMDsKKwkJc2RtX2Nm ZzMgPSAwOworCX0KKworCURCRygic2RtX2NmZzA9JWQiLCBzZG1fY2ZnMCk7CisJREJHKCJzZG1f Y2ZnMT0lZCIsIHNkbV9jZmcxKTsKKwlEQkcoInNkbV9jZmcyPSVkIiwgc2RtX2NmZzIpOworCURC Rygic2RtX2NmZzM9JWQiLCBzZG1fY2ZnMyk7CisKKwljYWxfY2ZnMTEgPSAodTMyKShnZW5fdmNv X2NsayAvICgyNTYgKiAxMDAwMDAwKSk7CisJY2FsX2NmZzEwID0gKHUzMikoKGdlbl92Y29fY2xr ICUgKDI1NiAqIDEwMDAwMDApKSAvIDEwMDAwMDApOworCURCRygiY2FsX2NmZzEwPSVkLCBjYWxf Y2ZnMTE9JWQiLCBjYWxfY2ZnMTAsIGNhbF9jZmcxMSk7CisKKwlwbGxfd3JpdGUoYmFzZSArIFJF R19EU0lfMjhubV9QSFlfUExMX0NIR1BVTVBfQ0ZHLCAweDAyKTsKKwlwbGxfd3JpdGUoYmFzZSAr IFJFR19EU0lfMjhubV9QSFlfUExMX0NBTF9DRkczLCAgICAweDJiKTsKKwlwbGxfd3JpdGUoYmFz ZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0NBTF9DRkc0LCAgICAweDA2KTsKKwlwbGxfd3JpdGUo YmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0xLREVUX0NGRzIsICAweDBkKTsKKworCXBsbF93 cml0ZShiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfU0RNX0NGRzEsIHNkbV9jZmcxKTsKKwlw bGxfd3JpdGUoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX1NETV9DRkcyLAorCQlEU0lfMjhu bV9QSFlfUExMX1NETV9DRkcyX0ZSRVFfU0VFRF83XzAoc2RtX2NmZzIpKTsKKwlwbGxfd3JpdGUo YmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX1NETV9DRkczLAorCQlEU0lfMjhubV9QSFlfUExM X1NETV9DRkczX0ZSRVFfU0VFRF8xNV84KHNkbV9jZmczKSk7CisJcGxsX3dyaXRlKGJhc2UgKyBS RUdfRFNJXzI4bm1fUEhZX1BMTF9TRE1fQ0ZHNCwgMHgwMCk7CisKKwkvKiBBZGQgaGFyZHdhcmUg cmVjb21tZW5kZWQgZGVsYXkgZm9yIGNvcnJlY3QgUExMIGNvbmZpZ3VyYXRpb24gKi8KKwlpZiAo cGxsXzI4bm0tPnZjb19kZWxheSkKKwkJdWRlbGF5KHBsbF8yOG5tLT52Y29fZGVsYXkpOworCisJ cGxsX3dyaXRlKGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZX1BMTF9SRUZDTEtfQ0ZHLCByZWZjbGtf Y2ZnKTsKKwlwbGxfd3JpdGUoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX1BXUkdFTl9DRkcs IDB4MDApOworCXBsbF93cml0ZShiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfVkNPTFBGX0NG RywgMHgzMSk7CisJcGxsX3dyaXRlKGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZX1BMTF9TRE1fQ0ZH MCwgICBzZG1fY2ZnMCk7CisJcGxsX3dyaXRlKGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZX1BMTF9D QUxfQ0ZHMCwgICAweDEyKTsKKwlwbGxfd3JpdGUoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExM X0NBTF9DRkc2LCAgIDB4MzApOworCXBsbF93cml0ZShiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9Q TExfQ0FMX0NGRzcsICAgMHgwMCk7CisJcGxsX3dyaXRlKGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZ X1BMTF9DQUxfQ0ZHOCwgICAweDYwKTsKKwlwbGxfd3JpdGUoYmFzZSArIFJFR19EU0lfMjhubV9Q SFlfUExMX0NBTF9DRkc5LCAgIDB4MDApOworCXBsbF93cml0ZShiYXNlICsgUkVHX0RTSV8yOG5t X1BIWV9QTExfQ0FMX0NGRzEwLCAgY2FsX2NmZzEwICYgMHhmZik7CisJcGxsX3dyaXRlKGJhc2Ug KyBSRUdfRFNJXzI4bm1fUEhZX1BMTF9DQUxfQ0ZHMTEsICBjYWxfY2ZnMTEgJiAweGZmKTsKKwlw bGxfd3JpdGUoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0VGVVNFX0NGRywgIDB4MjApOwor CisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgZHNpX3BsbF8yOG5tX2Nsa19pc19lbmFibGVk KHN0cnVjdCBjbGtfaHcgKmh3KQoreworCXN0cnVjdCBtc21fZHNpX3BsbCAqcGxsID0gaHdfY2xr X3RvX3BsbChodyk7CisJc3RydWN0IGRzaV9wbGxfMjhubSAqcGxsXzI4bm0gPSB0b19wbGxfMjhu bShwbGwpOworCisJcmV0dXJuIHBsbF8yOG5tX3BvbGxfZm9yX3JlYWR5KHBsbF8yOG5tLCBQT0xM X01BWF9SRUFEUywKKwkJCQkJUE9MTF9USU1FT1VUX1VTKTsKK30KKworc3RhdGljIHVuc2lnbmVk IGxvbmcgZHNpX3BsbF8yOG5tX2Nsa19yZWNhbGNfcmF0ZShzdHJ1Y3QgY2xrX2h3ICpodywKKwkJ dW5zaWduZWQgbG9uZyBwYXJlbnRfcmF0ZSkKK3sKKwlzdHJ1Y3QgbXNtX2RzaV9wbGwgKnBsbCA9 IGh3X2Nsa190b19wbGwoaHcpOworCXN0cnVjdCBkc2lfcGxsXzI4bm0gKnBsbF8yOG5tID0gdG9f cGxsXzI4bm0ocGxsKTsKKwl2b2lkIF9faW9tZW0gKmJhc2UgPSBwbGxfMjhubS0+bW1pbzsKKwl1 MzIgc2RtMCwgZG91Ymxlciwgc2RtX2J5cF9kaXY7CisJdTMyIHNkbV9kY19vZmYsIHNkbV9mcmVx X3NlZWQsIHNkbTIsIHNkbTM7CisJdTMyIHJlZl9jbGsgPSBWQ09fUkVGX0NMS19SQVRFOworCXVu c2lnbmVkIGxvbmcgdmNvX3JhdGU7CisKKwlWRVJCKCJwYXJlbnRfcmF0ZT0lbHUiLCBwYXJlbnRf cmF0ZSk7CisKKwkvKiBDaGVjayB0byBzZWUgaWYgdGhlIHJlZiBjbGsgZG91YmxlciBpcyBlbmFi bGVkICovCisJZG91YmxlciA9IHBsbF9yZWFkKGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZX1BMTF9S RUZDTEtfQ0ZHKSAmCisJCQlEU0lfMjhubV9QSFlfUExMX1JFRkNMS19DRkdfREJMUjsKKwlyZWZf Y2xrICs9IChkb3VibGVyICogVkNPX1JFRl9DTEtfUkFURSk7CisKKwkvKiBzZWUgaWYgaXQgaXMg aW50ZWdlciBtb2RlIG9yIHNkbSBtb2RlICovCisJc2RtMCA9IHBsbF9yZWFkKGJhc2UgKyBSRUdf RFNJXzI4bm1fUEhZX1BMTF9TRE1fQ0ZHMCk7CisJaWYgKHNkbTAgJiBEU0lfMjhubV9QSFlfUExM X1NETV9DRkcwX0JZUCkgeworCQkvKiBpbnRlZ2VyIG1vZGUgKi8KKwkJc2RtX2J5cF9kaXYgPSBG SUVMRCgKKwkJCQlwbGxfcmVhZChiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfU0RNX0NGRzAp LAorCQkJCURTSV8yOG5tX1BIWV9QTExfU0RNX0NGRzBfQllQX0RJVikgKyAxOworCQl2Y29fcmF0 ZSA9IHJlZl9jbGsgKiBzZG1fYnlwX2RpdjsKKwl9IGVsc2UgeworCQkvKiBzZG0gbW9kZSAqLwor CQlzZG1fZGNfb2ZmID0gRklFTEQoCisJCQkJcGxsX3JlYWQoYmFzZSArIFJFR19EU0lfMjhubV9Q SFlfUExMX1NETV9DRkcxKSwKKwkJCQlEU0lfMjhubV9QSFlfUExMX1NETV9DRkcxX0RDX09GRlNF VCk7CisJCURCRygic2RtX2RjX29mZiA9ICVkIiwgc2RtX2RjX29mZik7CisJCXNkbTIgPSBGSUVM RChwbGxfcmVhZChiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfU0RNX0NGRzIpLAorCQkJCURT SV8yOG5tX1BIWV9QTExfU0RNX0NGRzJfRlJFUV9TRUVEXzdfMCk7CisJCXNkbTMgPSBGSUVMRChw bGxfcmVhZChiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfU0RNX0NGRzMpLAorCQkJCURTSV8y OG5tX1BIWV9QTExfU0RNX0NGRzNfRlJFUV9TRUVEXzE1XzgpOworCQlzZG1fZnJlcV9zZWVkID0g KHNkbTMgPDwgOCkgfCBzZG0yOworCQlEQkcoInNkbV9mcmVxX3NlZWQgPSAlZCIsIHNkbV9mcmVx X3NlZWQpOworCisJCXZjb19yYXRlID0gKHJlZl9jbGsgKiAoc2RtX2RjX29mZiArIDEpKSArCisJ CQltdWx0X2ZyYWMocmVmX2Nsaywgc2RtX2ZyZXFfc2VlZCwgQklUKDE2KSk7CisJCURCRygidmNv IHJhdGUgPSAlbHUiLCB2Y29fcmF0ZSk7CisJfQorCisJREJHKCJyZXR1cm5pbmcgdmNvIHJhdGUg PSAlbHUiLCB2Y29fcmF0ZSk7CisKKwlyZXR1cm4gdmNvX3JhdGU7Cit9CisKK3N0YXRpYyBjb25z dCBzdHJ1Y3QgY2xrX29wcyBjbGtfb3BzX2RzaV9wbGxfMjhubV92Y28gPSB7CisJLnJvdW5kX3Jh dGUgPSBtc21fZHNpX3BsbF9oZWxwZXJfY2xrX3JvdW5kX3JhdGUsCisJLnNldF9yYXRlID0gZHNp X3BsbF8yOG5tX2Nsa19zZXRfcmF0ZSwKKwkucmVjYWxjX3JhdGUgPSBkc2lfcGxsXzI4bm1fY2xr X3JlY2FsY19yYXRlLAorCS5wcmVwYXJlID0gbXNtX2RzaV9wbGxfaGVscGVyX2Nsa19wcmVwYXJl LAorCS51bnByZXBhcmUgPSBtc21fZHNpX3BsbF9oZWxwZXJfY2xrX3VucHJlcGFyZSwKKwkuaXNf ZW5hYmxlZCA9IGRzaV9wbGxfMjhubV9jbGtfaXNfZW5hYmxlZCwKK307CisKKy8qCisgKiBQTEwg Q2FsbGJhY2tzCisgKi8KK3N0YXRpYyBpbnQgZHNpX3BsbF8yOG5tX2VuYWJsZV9zZXFfaHBtKHN0 cnVjdCBtc21fZHNpX3BsbCAqcGxsKQoreworCXN0cnVjdCBkc2lfcGxsXzI4bm0gKnBsbF8yOG5t ID0gdG9fcGxsXzI4bm0ocGxsKTsKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcGxsXzI4bm0tPnBk ZXYtPmRldjsKKwl2b2lkIF9faW9tZW0gKmJhc2UgPSBwbGxfMjhubS0+bW1pbzsKKwl1MzIgbWF4 X3JlYWRzID0gNSwgdGltZW91dF91cyA9IDEwMDsKKwlib29sIGxvY2tlZDsKKwl1MzIgdmFsOwor CWludCBpOworCisJREJHKCJpZD0lZCIsIHBsbF8yOG5tLT5pZCk7CisKKwlwbGxfMjhubV9zb2Z0 d2FyZV9yZXNldChwbGxfMjhubSk7CisKKwkvKgorCSAqIFBMTCBwb3dlciB1cCBzZXF1ZW5jZS4K KwkgKiBBZGQgbmVjZXNzYXJ5IGRlbGF5cyByZWNvbW1lbmRlZCBieSBoYXJkd2FyZS4KKwkgKi8K Kwl2YWwgPSBEU0lfMjhubV9QSFlfUExMX0dMQl9DRkdfUExMX1BXUkROX0I7CisJcGxsX3dyaXRl X3VkZWxheShiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfR0xCX0NGRywgdmFsLCAxKTsKKwor CXZhbCB8PSBEU0lfMjhubV9QSFlfUExMX0dMQl9DRkdfUExMX1BXUkdFTl9QV1JETl9COworCXBs bF93cml0ZV91ZGVsYXkoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0dMQl9DRkcsIHZhbCwg MjAwKTsKKworCXZhbCB8PSBEU0lfMjhubV9QSFlfUExMX0dMQl9DRkdfUExMX0xET19QV1JETl9C OworCXBsbF93cml0ZV91ZGVsYXkoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0dMQl9DRkcs IHZhbCwgNTAwKTsKKworCXZhbCB8PSBEU0lfMjhubV9QSFlfUExMX0dMQl9DRkdfUExMX0VOQUJM RTsKKwlwbGxfd3JpdGVfdWRlbGF5KGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZX1BMTF9HTEJfQ0ZH LCB2YWwsIDYwMCk7CisKKwlmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CisJCS8qIERTSSBVbmlw aHkgbG9jayBkZXRlY3Qgc2V0dGluZyAqLworCQlwbGxfd3JpdGVfdWRlbGF5KGJhc2UgKyBSRUdf RFNJXzI4bm1fUEhZX1BMTF9MS0RFVF9DRkcyLAorCQkJCTB4MGMsIDEwMCk7CisJCXBsbF93cml0 ZShiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfTEtERVRfQ0ZHMiwgMHgwZCk7CisKKwkJLyog cG9sbCBmb3IgUExMIHJlYWR5IHN0YXR1cyAqLworCQlsb2NrZWQgPSBwbGxfMjhubV9wb2xsX2Zv cl9yZWFkeShwbGxfMjhubSwKKwkJCQkJCW1heF9yZWFkcywgdGltZW91dF91cyk7CisJCWlmIChs b2NrZWQpCisJCQlicmVhazsKKworCQlwbGxfMjhubV9zb2Z0d2FyZV9yZXNldChwbGxfMjhubSk7 CisKKwkJLyoKKwkJICogUExMIHBvd2VyIHVwIHNlcXVlbmNlLgorCQkgKiBBZGQgbmVjZXNzYXJ5 IGRlbGF5cyByZWNvbW1lbmRlZCBieSBoYXJkd2FyZS4KKwkJICovCisJCXZhbCA9IERTSV8yOG5t X1BIWV9QTExfR0xCX0NGR19QTExfUFdSRE5fQjsKKwkJcGxsX3dyaXRlX3VkZWxheShiYXNlICsg UkVHX0RTSV8yOG5tX1BIWV9QTExfR0xCX0NGRywgdmFsLCAxKTsKKworCQl2YWwgfD0gRFNJXzI4 bm1fUEhZX1BMTF9HTEJfQ0ZHX1BMTF9QV1JHRU5fUFdSRE5fQjsKKwkJcGxsX3dyaXRlX3VkZWxh eShiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfR0xCX0NGRywgdmFsLCAyMDApOworCisJCXZh bCB8PSBEU0lfMjhubV9QSFlfUExMX0dMQl9DRkdfUExMX0xET19QV1JETl9COworCQlwbGxfd3Jp dGVfdWRlbGF5KGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZX1BMTF9HTEJfQ0ZHLCB2YWwsIDI1MCk7 CisKKwkJdmFsICY9IH5EU0lfMjhubV9QSFlfUExMX0dMQl9DRkdfUExMX0xET19QV1JETl9COwor CQlwbGxfd3JpdGVfdWRlbGF5KGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZX1BMTF9HTEJfQ0ZHLCB2 YWwsIDIwMCk7CisKKwkJdmFsIHw9IERTSV8yOG5tX1BIWV9QTExfR0xCX0NGR19QTExfTERPX1BX UkROX0I7CisJCXBsbF93cml0ZV91ZGVsYXkoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0dM Ql9DRkcsIHZhbCwgNTAwKTsKKworCQl2YWwgfD0gRFNJXzI4bm1fUEhZX1BMTF9HTEJfQ0ZHX1BM TF9FTkFCTEU7CisJCXBsbF93cml0ZV91ZGVsYXkoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExM X0dMQl9DRkcsIHZhbCwgNjAwKTsKKwl9CisKKwlpZiAodW5saWtlbHkoIWxvY2tlZCkpCisJCWRl dl9lcnIoZGV2LCAiRFNJIFBMTCBsb2NrIGZhaWxlZFxuIik7CisJZWxzZQorCQlEQkcoIkRTSSBQ TEwgTG9jayBzdWNjZXNzIik7CisKKwlyZXR1cm4gbG9ja2VkID8gMCA6IC1FSU5WQUw7Cit9CisK K3N0YXRpYyBpbnQgZHNpX3BsbF8yOG5tX2VuYWJsZV9zZXFfbHAoc3RydWN0IG1zbV9kc2lfcGxs ICpwbGwpCit7CisJc3RydWN0IGRzaV9wbGxfMjhubSAqcGxsXzI4bm0gPSB0b19wbGxfMjhubShw bGwpOworCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwbGxfMjhubS0+cGRldi0+ZGV2OworCXZvaWQg X19pb21lbSAqYmFzZSA9IHBsbF8yOG5tLT5tbWlvOworCWJvb2wgbG9ja2VkOworCXUzMiBtYXhf cmVhZHMgPSAxMCwgdGltZW91dF91cyA9IDUwOworCXUzMiB2YWw7CisKKwlEQkcoImlkPSVkIiwg cGxsXzI4bm0tPmlkKTsKKworCXBsbF8yOG5tX3NvZnR3YXJlX3Jlc2V0KHBsbF8yOG5tKTsKKwor CS8qCisJICogUExMIHBvd2VyIHVwIHNlcXVlbmNlLgorCSAqIEFkZCBuZWNlc3NhcnkgZGVsYXlz IHJlY29tbWVuZGVkIGJ5IGhhcmR3YXJlLgorCSAqLworCXBsbF93cml0ZV9uZGVsYXkoYmFzZSAr IFJFR19EU0lfMjhubV9QSFlfUExMX0NBTF9DRkcxLCAweDM0LCA1MDApOworCisJdmFsID0gRFNJ XzI4bm1fUEhZX1BMTF9HTEJfQ0ZHX1BMTF9QV1JETl9COworCXBsbF93cml0ZV9uZGVsYXkoYmFz ZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0dMQl9DRkcsIHZhbCwgNTAwKTsKKworCXZhbCB8PSBE U0lfMjhubV9QSFlfUExMX0dMQl9DRkdfUExMX1BXUkdFTl9QV1JETl9COworCXBsbF93cml0ZV9u ZGVsYXkoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX0dMQl9DRkcsIHZhbCwgNTAwKTsKKwor CXZhbCB8PSBEU0lfMjhubV9QSFlfUExMX0dMQl9DRkdfUExMX0xET19QV1JETl9CIHwKKwkJRFNJ XzI4bm1fUEhZX1BMTF9HTEJfQ0ZHX1BMTF9FTkFCTEU7CisJcGxsX3dyaXRlX25kZWxheShiYXNl ICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfR0xCX0NGRywgdmFsLCA1MDApOworCisJLyogRFNJIFBM TCB0b2dnbGUgbG9jayBkZXRlY3Qgc2V0dGluZyAqLworCXBsbF93cml0ZV9uZGVsYXkoYmFzZSAr IFJFR19EU0lfMjhubV9QSFlfUExMX0xLREVUX0NGRzIsIDB4MDQsIDUwMCk7CisJcGxsX3dyaXRl X3VkZWxheShiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfTEtERVRfQ0ZHMiwgMHgwNSwgNTEy KTsKKworCWxvY2tlZCA9IHBsbF8yOG5tX3BvbGxfZm9yX3JlYWR5KHBsbF8yOG5tLCBtYXhfcmVh ZHMsIHRpbWVvdXRfdXMpOworCisJaWYgKHVubGlrZWx5KCFsb2NrZWQpKQorCQlkZXZfZXJyKGRl diwgIkRTSSBQTEwgbG9jayBmYWlsZWRcbiIpOworCWVsc2UKKwkJREJHKCJEU0kgUExMIGxvY2sg c3VjY2VzcyIpOworCisJcmV0dXJuIGxvY2tlZCA/IDAgOiAtRUlOVkFMOworfQorCitzdGF0aWMg dm9pZCBkc2lfcGxsXzI4bm1fZGlzYWJsZV9zZXEoc3RydWN0IG1zbV9kc2lfcGxsICpwbGwpCit7 CisJc3RydWN0IGRzaV9wbGxfMjhubSAqcGxsXzI4bm0gPSB0b19wbGxfMjhubShwbGwpOworCisJ REJHKCJpZD0lZCIsIHBsbF8yOG5tLT5pZCk7CisJcGxsX3dyaXRlKHBsbF8yOG5tLT5tbWlvICsg UkVHX0RTSV8yOG5tX1BIWV9QTExfR0xCX0NGRywgMHgwMCk7Cit9CisKK3N0YXRpYyB2b2lkIGRz aV9wbGxfMjhubV9zYXZlX3N0YXRlKHN0cnVjdCBtc21fZHNpX3BsbCAqcGxsKQoreworCXN0cnVj dCBkc2lfcGxsXzI4bm0gKnBsbF8yOG5tID0gdG9fcGxsXzI4bm0ocGxsKTsKKwlzdHJ1Y3QgcGxs XzI4bm1fY2FjaGVkX3N0YXRlICpjYWNoZWRfc3RhdGUgPSAmcGxsXzI4bm0tPmNhY2hlZF9zdGF0 ZTsKKwl2b2lkIF9faW9tZW0gKmJhc2UgPSBwbGxfMjhubS0+bW1pbzsKKworCWNhY2hlZF9zdGF0 ZS0+cG9zdGRpdjMgPQorCQkJcGxsX3JlYWQoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX1BP U1RESVYzX0NGRyk7CisJY2FjaGVkX3N0YXRlLT5wb3N0ZGl2MSA9CisJCQlwbGxfcmVhZChiYXNl ICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfUE9TVERJVjFfQ0ZHKTsKKwljYWNoZWRfc3RhdGUtPmJ5 dGVfbXV4ID0gcGxsX3JlYWQoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExMX1ZSRUdfQ0ZHKTsK KwljYWNoZWRfc3RhdGUtPnZjb19yYXRlID0gX19jbGtfZ2V0X3JhdGUocGxsLT5jbGtfaHcuY2xr KTsKK30KKworc3RhdGljIGludCBkc2lfcGxsXzI4bm1fcmVzdG9yZV9zdGF0ZShzdHJ1Y3QgbXNt X2RzaV9wbGwgKnBsbCkKK3sKKwlzdHJ1Y3QgZHNpX3BsbF8yOG5tICpwbGxfMjhubSA9IHRvX3Bs bF8yOG5tKHBsbCk7CisJc3RydWN0IHBsbF8yOG5tX2NhY2hlZF9zdGF0ZSAqY2FjaGVkX3N0YXRl ID0gJnBsbF8yOG5tLT5jYWNoZWRfc3RhdGU7CisJdm9pZCBfX2lvbWVtICpiYXNlID0gcGxsXzI4 bm0tPm1taW87CisJaW50IHJldDsKKworCWlmICgoY2FjaGVkX3N0YXRlLT52Y29fcmF0ZSAhPSAw KSAmJgorCQkoY2FjaGVkX3N0YXRlLT52Y29fcmF0ZSA9PSBfX2Nsa19nZXRfcmF0ZShwbGwtPmNs a19ody5jbGspKSkgeworCQlyZXQgPSBkc2lfcGxsXzI4bm1fY2xrX3NldF9yYXRlKCZwbGwtPmNs a19odywKKwkJCQkJCWNhY2hlZF9zdGF0ZS0+dmNvX3JhdGUsIDApOworCQlpZiAocmV0KSB7CisJ CQlkZXZfZXJyKCZwbGxfMjhubS0+cGRldi0+ZGV2LAorCQkJCSJyZXN0b3JlIHZjbyByYXRlIGZh aWxlZC4gcmV0PSVkXG4iLCByZXQpOworCQkJcmV0dXJuIHJldDsKKwkJfQorCisJCXBsbF93cml0 ZShiYXNlICsgUkVHX0RTSV8yOG5tX1BIWV9QTExfUE9TVERJVjNfQ0ZHLAorCQkJCWNhY2hlZF9z dGF0ZS0+cG9zdGRpdjMpOworCQlwbGxfd3JpdGUoYmFzZSArIFJFR19EU0lfMjhubV9QSFlfUExM X1BPU1RESVYxX0NGRywKKwkJCQljYWNoZWRfc3RhdGUtPnBvc3RkaXYxKTsKKwkJcGxsX3dyaXRl KGJhc2UgKyBSRUdfRFNJXzI4bm1fUEhZX1BMTF9WUkVHX0NGRywKKwkJCQljYWNoZWRfc3RhdGUt PmJ5dGVfbXV4KTsKKworCQljYWNoZWRfc3RhdGUtPnZjb19yYXRlID0gMDsKKwl9CisKKwlyZXR1 cm4gMDsKK30KKworc3RhdGljIGludCBkc2lfcGxsXzI4bm1fZ2V0X3Byb3ZpZGVyKHN0cnVjdCBt c21fZHNpX3BsbCAqcGxsLAorCQkJCXN0cnVjdCBjbGsgKipieXRlX2Nsa19wcm92aWRlciwKKwkJ CQlzdHJ1Y3QgY2xrICoqcGl4ZWxfY2xrX3Byb3ZpZGVyKQoreworCXN0cnVjdCBkc2lfcGxsXzI4 bm0gKnBsbF8yOG5tID0gdG9fcGxsXzI4bm0ocGxsKTsKKworCWlmIChieXRlX2Nsa19wcm92aWRl cikKKwkJKmJ5dGVfY2xrX3Byb3ZpZGVyID0gcGxsXzI4bm0tPnByb3ZpZGVkX2Nsa3NbRFNJX0JZ VEVfUExMX0NMS107CisJaWYgKHBpeGVsX2Nsa19wcm92aWRlcikKKwkJKnBpeGVsX2Nsa19wcm92 aWRlciA9CisJCQkJcGxsXzI4bm0tPnByb3ZpZGVkX2Nsa3NbRFNJX1BJWEVMX1BMTF9DTEtdOwor CisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkIGRzaV9wbGxfMjhubV9kZXN0cm95KHN0cnVj dCBtc21fZHNpX3BsbCAqcGxsKQoreworCXN0cnVjdCBkc2lfcGxsXzI4bm0gKnBsbF8yOG5tID0g dG9fcGxsXzI4bm0ocGxsKTsKKwlpbnQgaTsKKworCW1zbV9kc2lfcGxsX2hlbHBlcl91bnJlZ2lz dGVyX2Nsa3MocGxsXzI4bm0tPnBkZXYsCisJCQkJCXBsbF8yOG5tLT5jbGtzLCBwbGxfMjhubS0+ bnVtX2Nsa3MpOworCisJZm9yIChpID0gMDsgaSA8IE5VTV9QUk9WSURFRF9DTEtTOyBpKyspCisJ CXBsbF8yOG5tLT5wcm92aWRlZF9jbGtzW2ldID0gTlVMTDsKKworCXBsbF8yOG5tLT5udW1fY2xr cyA9IDA7CisJcGxsXzI4bm0tPmNsa19kYXRhLmNsa3MgPSBOVUxMOworCXBsbF8yOG5tLT5jbGtf ZGF0YS5jbGtfbnVtID0gMDsKK30KKworc3RhdGljIGludCBwbGxfMjhubV9yZWdpc3RlcihzdHJ1 Y3QgZHNpX3BsbF8yOG5tICpwbGxfMjhubSkKK3sKKwljaGFyIGNsa19uYW1lWzMyXSwgcGFyZW50 MVszMl0sIHBhcmVudDJbMzJdLCB2Y29fbmFtZVszMl07CisJc3RydWN0IGNsa19pbml0X2RhdGEg dmNvX2luaXQgPSB7CisJCS5wYXJlbnRfbmFtZXMgPSAoY29uc3QgY2hhciAqW10peyAieG8iIH0s CisJCS5udW1fcGFyZW50cyA9IDEsCisJCS5uYW1lID0gdmNvX25hbWUsCisJCS5vcHMgPSAmY2xr X29wc19kc2lfcGxsXzI4bm1fdmNvLAorCX07CisJc3RydWN0IGRldmljZSAqZGV2ID0gJnBsbF8y OG5tLT5wZGV2LT5kZXY7CisJc3RydWN0IGNsayAqKmNsa3MgPSBwbGxfMjhubS0+Y2xrczsKKwlz dHJ1Y3QgY2xrICoqcHJvdmlkZWRfY2xrcyA9IHBsbF8yOG5tLT5wcm92aWRlZF9jbGtzOworCWlu dCBudW0gPSAwOworCWludCByZXQ7CisKKwlEQkcoIiVkIiwgcGxsXzI4bm0tPmlkKTsKKworCXNu cHJpbnRmKHZjb19uYW1lLCAzMiwgImRzaSVkdmNvX2NsayIsIHBsbF8yOG5tLT5pZCk7CisJcGxs XzI4bm0tPmJhc2UuY2xrX2h3LmluaXQgPSAmdmNvX2luaXQ7CisJY2xrc1tudW0rK10gPSBjbGtf cmVnaXN0ZXIoZGV2LCAmcGxsXzI4bm0tPmJhc2UuY2xrX2h3KTsKKworCXNucHJpbnRmKGNsa19u YW1lLCAzMiwgImRzaSVkYW5hbG9nX3Bvc3RkaXZfY2xrIiwgcGxsXzI4bm0tPmlkKTsKKwlzbnBy aW50ZihwYXJlbnQxLCAzMiwgImRzaSVkdmNvX2NsayIsIHBsbF8yOG5tLT5pZCk7CisJY2xrc1tu dW0rK10gPSBjbGtfcmVnaXN0ZXJfZGl2aWRlcihkZXYsIGNsa19uYW1lLAorCQkJcGFyZW50MSwg Q0xLX1NFVF9SQVRFX1BBUkVOVCwKKwkJCXBsbF8yOG5tLT5tbWlvICsKKwkJCVJFR19EU0lfMjhu bV9QSFlfUExMX1BPU1RESVYxX0NGRywKKwkJCTAsIDQsIDAsIE5VTEwpOworCisJc25wcmludGYo Y2xrX25hbWUsIDMyLCAiZHNpJWRpbmRpcmVjdF9wYXRoX2RpdjJfY2xrIiwgcGxsXzI4bm0tPmlk KTsKKwlzbnByaW50ZihwYXJlbnQxLCAzMiwgImRzaSVkYW5hbG9nX3Bvc3RkaXZfY2xrIiwgcGxs XzI4bm0tPmlkKTsKKwljbGtzW251bSsrXSA9IGNsa19yZWdpc3Rlcl9maXhlZF9mYWN0b3IoZGV2 LCBjbGtfbmFtZSwKKwkJCXBhcmVudDEsIENMS19TRVRfUkFURV9QQVJFTlQsCisJCQkxLCAyKTsK KworCXNucHJpbnRmKGNsa19uYW1lLCAzMiwgImRzaSVkcGxsIiwgcGxsXzI4bm0tPmlkKTsKKwlz bnByaW50ZihwYXJlbnQxLCAzMiwgImRzaSVkdmNvX2NsayIsIHBsbF8yOG5tLT5pZCk7CisJY2xr c1tudW0rK10gPSBwcm92aWRlZF9jbGtzW0RTSV9QSVhFTF9QTExfQ0xLXSA9CisJCQljbGtfcmVn aXN0ZXJfZGl2aWRlcihkZXYsIGNsa19uYW1lLAorCQkJCXBhcmVudDEsIDAsIHBsbF8yOG5tLT5t bWlvICsKKwkJCQlSRUdfRFNJXzI4bm1fUEhZX1BMTF9QT1NURElWM19DRkcsCisJCQkJMCwgOCwg MCwgTlVMTCk7CisKKwlzbnByaW50ZihjbGtfbmFtZSwgMzIsICJkc2klZGJ5dGVfbXV4IiwgcGxs XzI4bm0tPmlkKTsKKwlzbnByaW50ZihwYXJlbnQxLCAzMiwgImRzaSVkdmNvX2NsayIsIHBsbF8y OG5tLT5pZCk7CisJc25wcmludGYocGFyZW50MiwgMzIsICJkc2klZGluZGlyZWN0X3BhdGhfZGl2 Ml9jbGsiLCBwbGxfMjhubS0+aWQpOworCWNsa3NbbnVtKytdID0gY2xrX3JlZ2lzdGVyX211eChk ZXYsIGNsa19uYW1lLAorCQkJKGNvbnN0IGNoYXIgKltdKXsKKwkJCQlwYXJlbnQxLCBwYXJlbnQy CisJCQl9LCAyLCBDTEtfU0VUX1JBVEVfUEFSRU5ULCBwbGxfMjhubS0+bW1pbyArCisJCQlSRUdf RFNJXzI4bm1fUEhZX1BMTF9WUkVHX0NGRywgMSwgMSwgMCwgTlVMTCk7CisKKwlzbnByaW50Zihj bGtfbmFtZSwgMzIsICJkc2klZHBsbGJ5dGUiLCBwbGxfMjhubS0+aWQpOworCXNucHJpbnRmKHBh cmVudDEsIDMyLCAiZHNpJWRieXRlX211eCIsIHBsbF8yOG5tLT5pZCk7CisJY2xrc1tudW0rK10g PSBwcm92aWRlZF9jbGtzW0RTSV9CWVRFX1BMTF9DTEtdID0KKwkJCWNsa19yZWdpc3Rlcl9maXhl ZF9mYWN0b3IoZGV2LCBjbGtfbmFtZSwKKwkJCQlwYXJlbnQxLCBDTEtfU0VUX1JBVEVfUEFSRU5U LCAxLCA0KTsKKworCXBsbF8yOG5tLT5udW1fY2xrcyA9IG51bTsKKworCXBsbF8yOG5tLT5jbGtf ZGF0YS5jbGtfbnVtID0gTlVNX1BST1ZJREVEX0NMS1M7CisJcGxsXzI4bm0tPmNsa19kYXRhLmNs a3MgPSBwcm92aWRlZF9jbGtzOworCisJcmV0ID0gb2ZfY2xrX2FkZF9wcm92aWRlcihkZXYtPm9m X25vZGUsCisJCQlvZl9jbGtfc3JjX29uZWNlbGxfZ2V0LCAmcGxsXzI4bm0tPmNsa19kYXRhKTsK KwlpZiAocmV0KSB7CisJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIHJlZ2lzdGVyIGNsayBwcm92 aWRlcjogJWRcbiIsIHJldCk7CisJCXJldHVybiByZXQ7CisJfQorCisJcmV0dXJuIDA7Cit9CisK K3N0cnVjdCBtc21fZHNpX3BsbCAqbXNtX2RzaV9wbGxfMjhubV9pbml0KHN0cnVjdCBwbGF0Zm9y bV9kZXZpY2UgKnBkZXYsCisJCQkJCWVudW0gbXNtX2RzaV9waHlfdHlwZSB0eXBlLCBpbnQgaWQp Cit7CisJc3RydWN0IGRzaV9wbGxfMjhubSAqcGxsXzI4bm07CisJc3RydWN0IG1zbV9kc2lfcGxs ICpwbGw7CisJaW50IHJldDsKKworCWlmICghcGRldikKKwkJcmV0dXJuIEVSUl9QVFIoLUVOT0RF Vik7CisKKwlwbGxfMjhubSA9IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCBzaXplb2YoKnBsbF8y OG5tKSwgR0ZQX0tFUk5FTCk7CisJaWYgKCFwbGxfMjhubSkKKwkJcmV0dXJuIEVSUl9QVFIoLUVO T01FTSk7CisKKwlwbGxfMjhubS0+cGRldiA9IHBkZXY7CisJcGxsXzI4bm0tPmlkID0gaWQ7CisK KwlwbGxfMjhubS0+bW1pbyA9IG1zbV9pb3JlbWFwKHBkZXYsICJkc2lfcGxsIiwgIkRTSV9QTEwi KTsKKwlpZiAoSVNfRVJSX09SX05VTEwocGxsXzI4bm0tPm1taW8pKSB7CisJCWRldl9lcnIoJnBk ZXYtPmRldiwgIiVzOiBmYWlsZWQgdG8gbWFwIHBsbCBiYXNlXG4iLCBfX2Z1bmNfXyk7CisJCXJl dHVybiBFUlJfUFRSKC1FTk9NRU0pOworCX0KKworCXBsbCA9ICZwbGxfMjhubS0+YmFzZTsKKwlw bGwtPm1pbl9yYXRlID0gVkNPX01JTl9SQVRFOworCXBsbC0+bWF4X3JhdGUgPSBWQ09fTUFYX1JB VEU7CisJcGxsLT5nZXRfcHJvdmlkZXIgPSBkc2lfcGxsXzI4bm1fZ2V0X3Byb3ZpZGVyOworCXBs bC0+ZGVzdHJveSA9IGRzaV9wbGxfMjhubV9kZXN0cm95OworCXBsbC0+ZGlzYWJsZV9zZXEgPSBk c2lfcGxsXzI4bm1fZGlzYWJsZV9zZXE7CisJcGxsLT5zYXZlX3N0YXRlID0gZHNpX3BsbF8yOG5t X3NhdmVfc3RhdGU7CisJcGxsLT5yZXN0b3JlX3N0YXRlID0gZHNpX3BsbF8yOG5tX3Jlc3RvcmVf c3RhdGU7CisKKwlpZiAodHlwZSA9PSBNU01fRFNJX1BIWV8yOE5NX0hQTSkgeworCQlwbGxfMjhu bS0+dmNvX2RlbGF5ID0gMTsKKworCQlwbGwtPmVuX3NlcV9jbnQgPSAzOworCQlwbGwtPmVuYWJs ZV9zZXFzWzBdID0gZHNpX3BsbF8yOG5tX2VuYWJsZV9zZXFfaHBtOworCQlwbGwtPmVuYWJsZV9z ZXFzWzFdID0gZHNpX3BsbF8yOG5tX2VuYWJsZV9zZXFfaHBtOworCQlwbGwtPmVuYWJsZV9zZXFz WzJdID0gZHNpX3BsbF8yOG5tX2VuYWJsZV9zZXFfaHBtOworCX0gZWxzZSBpZiAodHlwZSA9PSBN U01fRFNJX1BIWV8yOE5NX0xQKSB7CisJCXBsbF8yOG5tLT52Y29fZGVsYXkgPSAxMDAwOworCisJ CXBsbC0+ZW5fc2VxX2NudCA9IDE7CisJCXBsbC0+ZW5hYmxlX3NlcXNbMF0gPSBkc2lfcGxsXzI4 bm1fZW5hYmxlX3NlcV9scDsKKwl9IGVsc2UgeworCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJwaHkg dHlwZSAoJWQpIGlzIG5vdCAyOG5tXG4iLCB0eXBlKTsKKwkJcmV0dXJuIEVSUl9QVFIoLUVJTlZB TCk7CisJfQorCisJcmV0ID0gcGxsXzI4bm1fcmVnaXN0ZXIocGxsXzI4bm0pOworCWlmIChyZXQp IHsKKwkJZGV2X2VycigmcGRldi0+ZGV2LCAiZmFpbGVkIHRvIHJlZ2lzdGVyIFBMTDogJWRcbiIs IHJldCk7CisJCXJldHVybiBFUlJfUFRSKHJldCk7CisJfQorCisJcmV0dXJuIHBsbDsKK30KKwot LSAKVGhlIFF1YWxjb21tIElubm92YXRpb24gQ2VudGVyLCBJbmMuIGlzIGEgbWVtYmVyIG9mIHRo ZSBDb2RlIEF1cm9yYSBGb3J1bSwKaG9zdGVkIGJ5IFRoZSBMaW51eCBGb3VuZGF0aW9uCgpfX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFp bGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cDovL2xpc3RzLmZy ZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934425AbbEOREf (ORCPT ); Fri, 15 May 2015 13:04:35 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:56518 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934149AbbEOREb (ORCPT ); Fri, 15 May 2015 13:04:31 -0400 From: Hai Li To: dri-devel@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, robdclark@gmail.com, Hai Li , Archit Taneja , Stephane Viau , Wentao Xu Subject: [PATCH 1/3] drm/msm/dsi: Add DSI PLL clock driver support Date: Fri, 15 May 2015 13:04:04 -0400 Message-Id: <1431709446-31429-2-git-send-email-hali@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1431709446-31429-1-git-send-email-hali@codeaurora.org> References: <1431709446-31429-1-git-send-email-hali@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org DSI byte clock and pixel clocks are sourced from DSI PLL. This change adds the DSI PLL source clock driver under common clock framework. This change handles DSI 28nm PLL only. Signed-off-by: Hai Li Signed-off-by: Archit Taneja Signed-off-by: Stephane Viau Signed-off-by: Wentao Xu --- drivers/gpu/drm/msm/Kconfig | 7 + drivers/gpu/drm/msm/Makefile | 5 + drivers/gpu/drm/msm/dsi/dsi.h | 3 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 10 +- drivers/gpu/drm/msm/dsi/dsi_phy.c | 3 +- drivers/gpu/drm/msm/dsi/pll/dsi_pll.c | 164 ++++++++ drivers/gpu/drm/msm/dsi/pll/dsi_pll.h | 89 ++++ drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c | 652 +++++++++++++++++++++++++++++ 8 files changed, 926 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/msm/dsi/pll/dsi_pll.c create mode 100644 drivers/gpu/drm/msm/dsi/pll/dsi_pll.h create mode 100644 drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 0a6f676..08ba8d0 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -46,3 +46,10 @@ config DRM_MSM_DSI Choose this option if you have a need for MIPI DSI connector support. +config DRM_MSM_DSI_PLL + bool "Enable DSI PLL driver in MSM DRM" + depends on DRM_MSM_DSI && COMMON_CLK + default y + help + Choose this option to enable DSI PLL driver which provides DSI + source clocks under common clock framework. diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index ab20867..16a81b9 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -1,4 +1,5 @@ ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/msm +ccflags-$(CONFIG_DRM_MSM_DSI_PLL) += -Idrivers/gpu/drm/msm/dsi msm-y := \ adreno/adreno_device.o \ @@ -50,10 +51,14 @@ msm-y := \ msm-$(CONFIG_DRM_MSM_FBDEV) += msm_fbdev.o msm-$(CONFIG_COMMON_CLK) += mdp/mdp4/mdp4_lvds_pll.o + msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \ dsi/dsi_host.o \ dsi/dsi_manager.o \ dsi/dsi_phy.o \ mdp/mdp5/mdp5_cmd_encoder.o +msm-$(CONFIG_DRM_MSM_DSI_PLL) += dsi/pll/dsi_pll.o \ + dsi/pll/dsi_pll_28nm.o + obj-$(CONFIG_DRM_MSM) += msm.o diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 10f54d4..321964a 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -103,7 +103,8 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi); struct msm_dsi_phy; enum msm_dsi_phy_type { MSM_DSI_PHY_UNKNOWN, - MSM_DSI_PHY_28NM, + MSM_DSI_PHY_28NM_HPM, + MSM_DSI_PHY_28NM_LP, MSM_DSI_PHY_MAX }; struct msm_dsi_phy *msm_dsi_phy_init(struct platform_device *pdev, diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 360b765..f7ba890 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -64,7 +64,7 @@ static const struct dsi_config dsi_cfgs[] = { .major = MSM_DSI_VER_MAJOR_6G, .minor = MSM_DSI_6G_VER_MINOR_V1_0, .io_offset = DSI_6G_REG_SHIFT, - .phy_type = MSM_DSI_PHY_28NM, + .phy_type = MSM_DSI_PHY_28NM_HPM, .reg_cfg = { .num = 4, .regs = { @@ -79,7 +79,7 @@ static const struct dsi_config dsi_cfgs[] = { .major = MSM_DSI_VER_MAJOR_6G, .minor = MSM_DSI_6G_VER_MINOR_V1_1, .io_offset = DSI_6G_REG_SHIFT, - .phy_type = MSM_DSI_PHY_28NM, + .phy_type = MSM_DSI_PHY_28NM_HPM, .reg_cfg = { .num = 4, .regs = { @@ -94,7 +94,7 @@ static const struct dsi_config dsi_cfgs[] = { .major = MSM_DSI_VER_MAJOR_6G, .minor = MSM_DSI_6G_VER_MINOR_V1_1_1, .io_offset = DSI_6G_REG_SHIFT, - .phy_type = MSM_DSI_PHY_28NM, + .phy_type = MSM_DSI_PHY_28NM_HPM, .reg_cfg = { .num = 4, .regs = { @@ -109,7 +109,7 @@ static const struct dsi_config dsi_cfgs[] = { .major = MSM_DSI_VER_MAJOR_6G, .minor = MSM_DSI_6G_VER_MINOR_V1_2, .io_offset = DSI_6G_REG_SHIFT, - .phy_type = MSM_DSI_PHY_28NM, + .phy_type = MSM_DSI_PHY_28NM_HPM, .reg_cfg = { .num = 4, .regs = { @@ -124,7 +124,7 @@ static const struct dsi_config dsi_cfgs[] = { .major = MSM_DSI_VER_MAJOR_6G, .minor = MSM_DSI_6G_VER_MINOR_V1_3_1, .io_offset = DSI_6G_REG_SHIFT, - .phy_type = MSM_DSI_PHY_28NM, + .phy_type = MSM_DSI_PHY_28NM_LP, .reg_cfg = { .num = 4, .regs = { diff --git a/drivers/gpu/drm/msm/dsi/dsi_phy.c b/drivers/gpu/drm/msm/dsi/dsi_phy.c index f0cea89..fc11474 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/dsi_phy.c @@ -311,7 +311,8 @@ struct msm_dsi_phy *msm_dsi_phy_init(struct platform_device *pdev, } switch (type) { - case MSM_DSI_PHY_28NM: + case MSM_DSI_PHY_28NM_HPM: + case MSM_DSI_PHY_28NM_LP: dsi_phy_func_init(28nm); break; default: diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c new file mode 100644 index 0000000..509376f --- /dev/null +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "dsi_pll.h" + +static int dsi_pll_enable(struct msm_dsi_pll *pll) +{ + int i, ret = 0; + + /* + * Certain PLLs do not allow VCO rate update when it is on. + * Keep track of their status to turn on/off after set rate success. + */ + if (unlikely(pll->pll_on)) + return 0; + + /* Try all enable sequences until one succeeds */ + for (i = 0; i < pll->en_seq_cnt; i++) { + ret = pll->enable_seqs[i](pll); + DBG("DSI PLL %s after sequence #%d", + ret ? "unlocked" : "locked", i + 1); + if (!ret) + break; + } + + if (ret) { + DRM_ERROR("DSI PLL failed to lock\n"); + return ret; + } + + pll->pll_on = true; + + return 0; +} + +static void dsi_pll_disable(struct msm_dsi_pll *pll) +{ + if (unlikely(!pll->pll_on)) + return; + + pll->disable_seq(pll); + + pll->pll_on = false; +} + +/* + * DSI PLL Helper functions + */ +long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + + if (rate < pll->min_rate) + return pll->min_rate; + else if (rate > pll->max_rate) + return pll->max_rate; + else + return rate; +} + +int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + int ret; + + /* + * Certain PLLs need to update the same VCO rate and registers + * after resume in suspend/resume scenario. + */ + if (pll->restore_state) { + ret = pll->restore_state(pll); + if (ret) + goto error; + } + + ret = dsi_pll_enable(pll); + +error: + return ret; +} + +void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + + if (pll->save_state) + pll->save_state(pll); + + dsi_pll_disable(pll); +} + +void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev, + struct clk **clks, u32 num_clks) +{ + of_clk_del_provider(pdev->dev.of_node); + + if (!num_clks || !clks) + return; + + do { + clk_unregister(clks[--num_clks]); + clks[num_clks] = NULL; + } while (num_clks); +} + +/* + * DSI PLL API + */ +int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll, + struct clk **byte_clk_provider, struct clk **pixel_clk_provider) +{ + if (pll->get_provider) + return pll->get_provider(pll, + byte_clk_provider, + pixel_clk_provider); + + return -EINVAL; +} + +void msm_dsi_pll_destroy(struct msm_dsi_pll *pll) +{ + if (pll->destroy) + pll->destroy(pll); +} + +struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev, + enum msm_dsi_phy_type type, int id) +{ + struct device *dev = &pdev->dev; + struct msm_dsi_pll *pll; + + switch (type) { + case MSM_DSI_PHY_28NM_HPM: + case MSM_DSI_PHY_28NM_LP: + pll = msm_dsi_pll_28nm_init(pdev, type, id); + break; + default: + pll = ERR_PTR(-ENXIO); + break; + } + + if (IS_ERR(pll)) { + dev_err(dev, "%s: failed to init DSI PLL\n", __func__); + return NULL; + } + + pll->type = type; + + DBG("DSI:%d PLL registered", id); + + return pll; +} + diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h new file mode 100644 index 0000000..5a3bb241 --- /dev/null +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __DSI_PLL_H__ +#define __DSI_PLL_H__ + +#include +#include + +#include "dsi.h" + +#define NUM_DSI_CLOCKS_MAX 6 +#define MAX_DSI_PLL_EN_SEQS 10 + +struct msm_dsi_pll { + enum msm_dsi_phy_type type; + + struct clk_hw clk_hw; + bool pll_on; + + unsigned long min_rate; + unsigned long max_rate; + u32 en_seq_cnt; + + int (*enable_seqs[MAX_DSI_PLL_EN_SEQS])(struct msm_dsi_pll *pll); + void (*disable_seq)(struct msm_dsi_pll *pll); + int (*get_provider)(struct msm_dsi_pll *pll, + struct clk **byte_clk_provider, + struct clk **pixel_clk_provider); + void (*destroy)(struct msm_dsi_pll *pll); + void (*save_state)(struct msm_dsi_pll *pll); + int (*restore_state)(struct msm_dsi_pll *pll); +}; + +#define hw_clk_to_pll(x) container_of(x, struct msm_dsi_pll, clk_hw) + +static inline void pll_write(void __iomem *reg, u32 data) +{ + msm_writel(data, reg); +} + +static inline u32 pll_read(const void __iomem *reg) +{ + return msm_readl(reg); +} + +static inline void pll_write_udelay(void __iomem *reg, u32 data, u32 delay_us) +{ + pll_write(reg, data); + udelay(delay_us); +} + +static inline void pll_write_ndelay(void __iomem *reg, u32 data, u32 delay_ns) +{ + pll_write((reg), data); + ndelay(delay_ns); +} + +/* + * DSI PLL Helper functions + */ + +/* clock callbacks */ +long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate); +int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw); +void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw); +/* misc */ +void msm_dsi_pll_helper_unregister_clks(struct platform_device *pdev, + struct clk **clks, u32 num_clks); + +/* + * Initialization for Each PLL Type + */ +struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev, + enum msm_dsi_phy_type type, int id); + +#endif /* __DSI_PLL_H__ */ + diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c new file mode 100644 index 0000000..eb8ac30 --- /dev/null +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c @@ -0,0 +1,652 @@ +/* + * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +#include "dsi_pll.h" +#include "dsi.xml.h" + +/* + * DSI PLL 28nm - clock diagram (eg: DSI0): + * + * dsi0analog_postdiv_clk + * | dsi0indirect_path_div2_clk + * | | + * +------+ | +----+ | |\ dsi0byte_mux + * dsi0vco_clk --o--| DIV1 |--o--| /2 |--o--| \ | + * | +------+ +----+ | m| | +----+ + * | | u|--o--| /4 |-- dsi0pllbyte + * | | x| +----+ + * o--------------------------| / + * | |/ + * | +------+ + * o----------| DIV3 |------------------------- dsi0pll + * +------+ + */ + +#define POLL_MAX_READS 10 +#define POLL_TIMEOUT_US 50 + +#define NUM_PROVIDED_CLKS 2 + +#define VCO_REF_CLK_RATE 19200000 +#define VCO_MIN_RATE 350000000 +#define VCO_MAX_RATE 750000000 + +#define DSI_BYTE_PLL_CLK 0 +#define DSI_PIXEL_PLL_CLK 1 + +#define LPFR_LUT_SIZE 10 +struct lpfr_cfg { + unsigned long vco_rate; + u32 resistance; +}; + +/* Loop filter resistance: */ +static const struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = { + { 479500000, 8 }, + { 480000000, 11 }, + { 575500000, 8 }, + { 576000000, 12 }, + { 610500000, 8 }, + { 659500000, 9 }, + { 671500000, 10 }, + { 672000000, 14 }, + { 708500000, 10 }, + { 750000000, 11 }, +}; + +struct pll_28nm_cached_state { + unsigned long vco_rate; + u8 postdiv3; + u8 postdiv1; + u8 byte_mux; +}; + +struct dsi_pll_28nm { + struct msm_dsi_pll base; + + int id; + struct platform_device *pdev; + void __iomem *mmio; + + int vco_delay; + + /* private clocks: */ + struct clk *clks[NUM_DSI_CLOCKS_MAX]; + u32 num_clks; + + /* clock-provider: */ + struct clk *provided_clks[NUM_PROVIDED_CLKS]; + struct clk_onecell_data clk_data; + + struct pll_28nm_cached_state cached_state; +}; + +#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base) + +static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, + u32 nb_tries, u32 timeout_us) +{ + bool pll_locked = false; + u32 val; + + while (nb_tries--) { + val = pll_read(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_STATUS); + pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY); + + if (pll_locked) + break; + + udelay(timeout_us); + } + DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* "); + + return pll_locked; +} + +static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm) +{ + void __iomem *base = pll_28nm->mmio; + + /* + * Add HW recommended delays after toggling the software + * reset bit off and back on. + */ + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, + DSI_28nm_PHY_PLL_TEST_CFG_PLL_SW_RESET, 1); + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, 0x00, 1); +} + +/* + * Clock Callbacks + */ +static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct device *dev = &pll_28nm->pdev->dev; + void __iomem *base = pll_28nm->mmio; + unsigned long div_fbx1000, gen_vco_clk; + u32 refclk_cfg, frac_n_mode, frac_n_value; + u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3; + u32 cal_cfg10, cal_cfg11; + u32 rem; + int i; + + VERB("rate=%lu, parent's=%lu", rate, parent_rate); + + /* Force postdiv2 to be div-4 */ + pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG, 3); + + /* Configure the Loop filter resistance */ + for (i = 0; i < LPFR_LUT_SIZE; i++) + if (rate <= lpfr_lut[i].vco_rate) + break; + if (i == LPFR_LUT_SIZE) { + dev_err(dev, "unable to get loop filter resistance. vco=%lu\n", + rate); + return -EINVAL; + } + pll_write(base + REG_DSI_28nm_PHY_PLL_LPFR_CFG, lpfr_lut[i].resistance); + + /* Loop filter capacitance values : c1 and c2 */ + pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG, 0x70); + pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG, 0x15); + + rem = rate % VCO_REF_CLK_RATE; + if (rem) { + refclk_cfg = DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR; + frac_n_mode = 1; + div_fbx1000 = rate / (VCO_REF_CLK_RATE / 500); + gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 500); + } else { + refclk_cfg = 0x0; + frac_n_mode = 0; + div_fbx1000 = rate / (VCO_REF_CLK_RATE / 1000); + gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 1000); + } + + DBG("refclk_cfg = %d", refclk_cfg); + + rem = div_fbx1000 % 1000; + frac_n_value = (rem << 16) / 1000; + + DBG("div_fb = %lu", div_fbx1000); + DBG("frac_n_value = %d", frac_n_value); + + DBG("Generated VCO Clock: %lu", gen_vco_clk); + rem = 0; + sdm_cfg1 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1); + sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK; + if (frac_n_mode) { + sdm_cfg0 = 0x0; + sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(0); + sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET( + (u32)(((div_fbx1000 / 1000) & 0x3f) - 1)); + sdm_cfg3 = frac_n_value >> 8; + sdm_cfg2 = frac_n_value & 0xff; + } else { + sdm_cfg0 = DSI_28nm_PHY_PLL_SDM_CFG0_BYP; + sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV( + (u32)(((div_fbx1000 / 1000) & 0x3f) - 1)); + sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(0); + sdm_cfg2 = 0; + sdm_cfg3 = 0; + } + + DBG("sdm_cfg0=%d", sdm_cfg0); + DBG("sdm_cfg1=%d", sdm_cfg1); + DBG("sdm_cfg2=%d", sdm_cfg2); + DBG("sdm_cfg3=%d", sdm_cfg3); + + cal_cfg11 = (u32)(gen_vco_clk / (256 * 1000000)); + cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000); + DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11); + + pll_write(base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG, 0x02); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG3, 0x2b); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG4, 0x06); + pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); + + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1, sdm_cfg1); + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2, + DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2)); + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3, + DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3)); + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00); + + /* Add hardware recommended delay for correct PLL configuration */ + if (pll_28nm->vco_delay) + udelay(pll_28nm->vco_delay); + + pll_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg); + pll_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00); + pll_write(base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG, 0x31); + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0, sdm_cfg0); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG0, 0x12); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG6, 0x30); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG7, 0x00); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG8, 0x60); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG9, 0x00); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG10, cal_cfg10 & 0xff); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG11, cal_cfg11 & 0xff); + pll_write(base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG, 0x20); + + return 0; +} + +static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS, + POLL_TIMEOUT_US); +} + +static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + void __iomem *base = pll_28nm->mmio; + u32 sdm0, doubler, sdm_byp_div; + u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3; + u32 ref_clk = VCO_REF_CLK_RATE; + unsigned long vco_rate; + + VERB("parent_rate=%lu", parent_rate); + + /* Check to see if the ref clk doubler is enabled */ + doubler = pll_read(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) & + DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR; + ref_clk += (doubler * VCO_REF_CLK_RATE); + + /* see if it is integer mode or sdm mode */ + sdm0 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0); + if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) { + /* integer mode */ + sdm_byp_div = FIELD( + pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0), + DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1; + vco_rate = ref_clk * sdm_byp_div; + } else { + /* sdm mode */ + sdm_dc_off = FIELD( + pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1), + DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET); + DBG("sdm_dc_off = %d", sdm_dc_off); + sdm2 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2), + DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0); + sdm3 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3), + DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8); + sdm_freq_seed = (sdm3 << 8) | sdm2; + DBG("sdm_freq_seed = %d", sdm_freq_seed); + + vco_rate = (ref_clk * (sdm_dc_off + 1)) + + mult_frac(ref_clk, sdm_freq_seed, BIT(16)); + DBG("vco rate = %lu", vco_rate); + } + + DBG("returning vco rate = %lu", vco_rate); + + return vco_rate; +} + +static const struct clk_ops clk_ops_dsi_pll_28nm_vco = { + .round_rate = msm_dsi_pll_helper_clk_round_rate, + .set_rate = dsi_pll_28nm_clk_set_rate, + .recalc_rate = dsi_pll_28nm_clk_recalc_rate, + .prepare = msm_dsi_pll_helper_clk_prepare, + .unprepare = msm_dsi_pll_helper_clk_unprepare, + .is_enabled = dsi_pll_28nm_clk_is_enabled, +}; + +/* + * PLL Callbacks + */ +static int dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct device *dev = &pll_28nm->pdev->dev; + void __iomem *base = pll_28nm->mmio; + u32 max_reads = 5, timeout_us = 100; + bool locked; + u32 val; + int i; + + DBG("id=%d", pll_28nm->id); + + pll_28nm_software_reset(pll_28nm); + + /* + * PLL power up sequence. + * Add necessary delays recommended by hardware. + */ + val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600); + + for (i = 0; i < 2; i++) { + /* DSI Uniphy lock detect setting */ + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, + 0x0c, 100); + pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); + + /* poll for PLL ready status */ + locked = pll_28nm_poll_for_ready(pll_28nm, + max_reads, timeout_us); + if (locked) + break; + + pll_28nm_software_reset(pll_28nm); + + /* + * PLL power up sequence. + * Add necessary delays recommended by hardware. + */ + val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 250); + + val &= ~DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600); + } + + if (unlikely(!locked)) + dev_err(dev, "DSI PLL lock failed\n"); + else + DBG("DSI PLL Lock success"); + + return locked ? 0 : -EINVAL; +} + +static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct device *dev = &pll_28nm->pdev->dev; + void __iomem *base = pll_28nm->mmio; + bool locked; + u32 max_reads = 10, timeout_us = 50; + u32 val; + + DBG("id=%d", pll_28nm->id); + + pll_28nm_software_reset(pll_28nm); + + /* + * PLL power up sequence. + * Add necessary delays recommended by hardware. + */ + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34, 500); + + val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B | + DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + /* DSI PLL toggle lock detect setting */ + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x04, 500); + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x05, 512); + + locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); + + if (unlikely(!locked)) + dev_err(dev, "DSI PLL lock failed\n"); + else + DBG("DSI PLL lock success"); + + return locked ? 0 : -EINVAL; +} + +static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + DBG("id=%d", pll_28nm->id); + pll_write(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00); +} + +static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; + void __iomem *base = pll_28nm->mmio; + + cached_state->postdiv3 = + pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG); + cached_state->postdiv1 = + pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG); + cached_state->byte_mux = pll_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG); + cached_state->vco_rate = __clk_get_rate(pll->clk_hw.clk); +} + +static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; + void __iomem *base = pll_28nm->mmio; + int ret; + + if ((cached_state->vco_rate != 0) && + (cached_state->vco_rate == __clk_get_rate(pll->clk_hw.clk))) { + ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw, + cached_state->vco_rate, 0); + if (ret) { + dev_err(&pll_28nm->pdev->dev, + "restore vco rate failed. ret=%d\n", ret); + return ret; + } + + pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, + cached_state->postdiv3); + pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, + cached_state->postdiv1); + pll_write(base + REG_DSI_28nm_PHY_PLL_VREG_CFG, + cached_state->byte_mux); + + cached_state->vco_rate = 0; + } + + return 0; +} + +static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll, + struct clk **byte_clk_provider, + struct clk **pixel_clk_provider) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + if (byte_clk_provider) + *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK]; + if (pixel_clk_provider) + *pixel_clk_provider = + pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK]; + + return 0; +} + +static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + int i; + + msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev, + pll_28nm->clks, pll_28nm->num_clks); + + for (i = 0; i < NUM_PROVIDED_CLKS; i++) + pll_28nm->provided_clks[i] = NULL; + + pll_28nm->num_clks = 0; + pll_28nm->clk_data.clks = NULL; + pll_28nm->clk_data.clk_num = 0; +} + +static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) +{ + char clk_name[32], parent1[32], parent2[32], vco_name[32]; + struct clk_init_data vco_init = { + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .name = vco_name, + .ops = &clk_ops_dsi_pll_28nm_vco, + }; + struct device *dev = &pll_28nm->pdev->dev; + struct clk **clks = pll_28nm->clks; + struct clk **provided_clks = pll_28nm->provided_clks; + int num = 0; + int ret; + + DBG("%d", pll_28nm->id); + + snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); + pll_28nm->base.clk_hw.init = &vco_init; + clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw); + + snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->id); + snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); + clks[num++] = clk_register_divider(dev, clk_name, + parent1, CLK_SET_RATE_PARENT, + pll_28nm->mmio + + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, + 0, 4, 0, NULL); + + snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); + snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->id); + clks[num++] = clk_register_fixed_factor(dev, clk_name, + parent1, CLK_SET_RATE_PARENT, + 1, 2); + + snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id); + snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); + clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] = + clk_register_divider(dev, clk_name, + parent1, 0, pll_28nm->mmio + + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, + 0, 8, 0, NULL); + + snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->id); + snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); + snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); + clks[num++] = clk_register_mux(dev, clk_name, + (const char *[]){ + parent1, parent2 + }, 2, CLK_SET_RATE_PARENT, pll_28nm->mmio + + REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL); + + snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); + snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->id); + clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] = + clk_register_fixed_factor(dev, clk_name, + parent1, CLK_SET_RATE_PARENT, 1, 4); + + pll_28nm->num_clks = num; + + pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS; + pll_28nm->clk_data.clks = provided_clks; + + ret = of_clk_add_provider(dev->of_node, + of_clk_src_onecell_get, &pll_28nm->clk_data); + if (ret) { + dev_err(dev, "failed to register clk provider: %d\n", ret); + return ret; + } + + return 0; +} + +struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev, + enum msm_dsi_phy_type type, int id) +{ + struct dsi_pll_28nm *pll_28nm; + struct msm_dsi_pll *pll; + int ret; + + if (!pdev) + return ERR_PTR(-ENODEV); + + pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL); + if (!pll_28nm) + return ERR_PTR(-ENOMEM); + + pll_28nm->pdev = pdev; + pll_28nm->id = id; + + pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); + if (IS_ERR_OR_NULL(pll_28nm->mmio)) { + dev_err(&pdev->dev, "%s: failed to map pll base\n", __func__); + return ERR_PTR(-ENOMEM); + } + + pll = &pll_28nm->base; + pll->min_rate = VCO_MIN_RATE; + pll->max_rate = VCO_MAX_RATE; + pll->get_provider = dsi_pll_28nm_get_provider; + pll->destroy = dsi_pll_28nm_destroy; + pll->disable_seq = dsi_pll_28nm_disable_seq; + pll->save_state = dsi_pll_28nm_save_state; + pll->restore_state = dsi_pll_28nm_restore_state; + + if (type == MSM_DSI_PHY_28NM_HPM) { + pll_28nm->vco_delay = 1; + + pll->en_seq_cnt = 3; + pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_hpm; + pll->enable_seqs[1] = dsi_pll_28nm_enable_seq_hpm; + pll->enable_seqs[2] = dsi_pll_28nm_enable_seq_hpm; + } else if (type == MSM_DSI_PHY_28NM_LP) { + pll_28nm->vco_delay = 1000; + + pll->en_seq_cnt = 1; + pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_lp; + } else { + dev_err(&pdev->dev, "phy type (%d) is not 28nm\n", type); + return ERR_PTR(-EINVAL); + } + + ret = pll_28nm_register(pll_28nm); + if (ret) { + dev_err(&pdev->dev, "failed to register PLL: %d\n", ret); + return ERR_PTR(ret); + } + + return pll; +} + -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation