diff for duplicates of <1488547113.2557.44.camel@synopsys.com> diff --git a/a/1.txt b/N1/1.txt index 1a5bc4f..202b008 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,265 +1,495 @@ -SGkgTWljaGFlbCwgU3RlcGhlbiwNCg0KT24gVHVlLCAyMDE3LTAyLTIxIGF0IDE2OjExICswMzAw -LCBWbGFkIFpha2hhcm92IHdyb3RlOg0KPiBBWFMxMFggYm9hcmRzIG1hbmFnZXMgaXQncyBjbG9j -a3MgdXNpbmcgdmFyaW91cyBQTExzLiBUaGVzZSBQTEwgaGFzIHNhbWUNCj4gZGl2aWRlcnMgYW5k -IGNvcnJlc3BvbmRpbmcgY29udHJvbCByZWdpc3RlcnMgbWFwcGVkIHRvIGRpZmZlcmVudCBhZGRy -ZXNzZXMuDQo+IFNvIHdlIGFkZCBvbmUgY29tbW9uIGRyaXZlciBmb3Igc3VjaCBQTExzLg0KPiAN -Cj4gRWFjaCBQTEwgb24gQVhTMTBYIGJvYXJkIGNvbnNpc3Qgb2YgdGhyZWUgZGl2aWRlcnM6IElE -SVYsIEZCRElWIGFuZA0KPiBPRElWLiBPdXRwdXQgY2xvY2sgdmFsdWUgaXMgbWFuYWdlZCB1c2lu -ZyB0aGVzZSBkaXZpZGVycy4NCj4gDQo+IFdlIGFkZCBwcmUtZGVmaW5lZCB0YWJsZXMgd2l0aCBz -dXBwb3J0ZWQgcmF0ZSB2YWx1ZXMgYW5kIGFwcHJvcHJpYXRlDQo+IGNvbmZpZ3VyYXRpb25zIG9m -IElESVYsIEZCRElWIGFuZCBPRElWIGZvciBlYWNoIHZhbHVlLg0KPiANCj4gQXMgb2YgdG9kYXkg -d2UgYWRkIHN1cHBvcnQgZm9yIFBMTHMgdGhhdCBnZW5lcmF0ZSBjbG9jayBmb3IgdGhlDQo+IGZv -bGxvd2luZyBkZXZpY2VzOg0KPiDCoCogQVJDIGNvcmUgb24gQVhDIENQVSB0aWxlcy4NCj4gwqAq -IEFSQyBQR1Ugb24gQVJDIFNEUCBNYWluYm9hcmQuDQo+IGFuZCBtb3JlIHRvIGNvbWUgbGF0ZXIu -DQo+IA0KPiBBY2tlZC1ieTogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gU2lnbmVk -LW9mZi1ieTogVmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+DQo+IFNpZ25lZC1v -ZmYtYnk6IEpvc2UgQWJyZXUgPGpvYWJyZXVAc3lub3BzeXMuY29tPg0KPiBDYzogTWljaGFlbCBU -dXJxdWV0dGUgPG10dXJxdWV0dGVAYmF5bGlicmUuY29tPg0KPiBDYzogU3RlcGhlbiBCb3lkIDxz -Ym95ZEBjb2RlYXVyb3JhLm9yZz4NCj4gQ2M6IE1hcmsgUnV0bGFuZCA8bWFyay5ydXRsYW5kQGFy -bS5jb20+DQo+IC0tLQ0KPiBDYzogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gQ2hh -bmdlcyB2MS4udjINCj4gwqAtIFJlcGxhY2UgJ18nIHdpdGggJy0nIGluIGRldmljZSB0cmVlIG5v -ZGVzDQo+IA0KPiDCoC4uLi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxsLWNsb2Nr -LnR4dMKgwqDCoHzCoMKgMjggKysNCj4gwqBNQUlOVEFJTkVSU8KgwqDCoMKgwqDCoMKgwqDCoMKg -wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC -oMKgfMKgwqDCoDYgKw0KPiDCoGRyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZcKgwqDCoMKgwqDC -oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAxICsNCj4gwqBkcml2 -ZXJzL2Nsay9heHMxMHgvcGxsX2Nsb2NrLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC -oMKgwqDCoMKgwqB8IDM4NCArKysrKysrKysrKysrKysrKysrKysNCj4gwqA0IGZpbGVzIGNoYW5n -ZWQsIDQxOSBpbnNlcnRpb25zKCspDQo+IMKgY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp -b24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gwqBjcmVh -dGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IA0KPiBkaWZm -IC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxs -LWNsb2NrLnR4dA0KPiBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9z -bnBzLHBsbC1jbG9jay50eHQNCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gaW5kZXggMDAwMDAw -MC4uNTcwNjI0Ng0KPiAtLS0gL2Rldi9udWxsDQo+ICsrKyBiL0RvY3VtZW50YXRpb24vZGV2aWNl -dHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gQEAgLTAsMCArMSwyOCBA -QA0KPiArQmluZGluZyBmb3IgdGhlIEFYUzEwWCBHZW5lcmljIFBMTCBjbG9jaw0KPiArDQo+ICtU -aGlzIGJpbmRpbmcgdXNlcyB0aGUgY29tbW9uIGNsb2NrIGJpbmRpbmdbMV0uDQo+ICsNCj4gK1sx -XSBEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvY2xvY2svY2xvY2stYmluZGluZ3Mu -dHh0DQo+ICsNCj4gK1JlcXVpcmVkIHByb3BlcnRpZXM6DQo+ICstIGNvbXBhdGlibGU6IHNob3Vs -ZCBiZSAic25wcyxheHMxMHgtPG5hbWU+LXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgt -YXJjLXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgtcGd1LXBsbC1jbG9jayINCj4gKy0g -cmVnOiBzaG91bGQgYWx3YXlzIGNvbnRhaW4gMiBwYWlycyBhZGRyZXNzIC0gbGVuZ3RoOiBmaXJz -dCBmb3IgUExMIGNvbmZpZw0KPiArcmVnaXN0ZXJzIGFuZCBzZWNvbmQgZm9yIGNvcnJlc3BvbmRp -bmcgTE9DSyBDR1UgcmVnaXN0ZXIuDQo+ICstIGNsb2Nrczogc2hhbGwgYmUgdGhlIGlucHV0IHBh -cmVudCBjbG9jayBwaGFuZGxlIGZvciB0aGUgUExMLg0KPiArLSAjY2xvY2stY2VsbHM6IGZyb20g -Y29tbW9uIGNsb2NrIGJpbmRpbmc7IFNob3VsZCBhbHdheXMgYmUgc2V0IHRvIDAuDQo+ICsNCj4g -K0V4YW1wbGU6DQo+ICsJaW5wdXQtY2xrOiBpbnB1dC1jbGsgew0KPiArCQljbG9jay1mcmVxdWVu -Y3kgPSA8MzMzMzMzMzM+Ow0KPiArCQljb21wYXRpYmxlID0gImZpeGVkLWNsb2NrIjsNCj4gKwkJ -I2Nsb2NrLWNlbGxzID0gPDA+Ow0KPiArCX07DQo+ICsNCj4gKwljb3JlLWNsazogY29yZS1jbGtA -ODAgew0KPiArCQljb21wYXRpYmxlID0gInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2siOw0KPiAr -CQlyZWcgPSA8MHg4MCAweDEwIDB4MTAwIDB4MTA+Ow0KPiArCQkjY2xvY2stY2VsbHMgPSA8MD47 -DQo+ICsJCWNsb2NrcyA9IDwmaW5wdXQtY2xrPjsNCj4gKwl9Ow0KPiBkaWZmIC0tZ2l0IGEvTUFJ -TlRBSU5FUlMgYi9NQUlOVEFJTkVSUw0KPiBpbmRleCAzOTYwZTdmLi41ODA1ODMzIDEwMDY0NA0K -PiAtLS0gYS9NQUlOVEFJTkVSUw0KPiArKysgYi9NQUlOVEFJTkVSUw0KPiBAQCAtMTE5MTAsNiAr -MTE5MTAsMTIgQEAgRjoJYXJjaC9hcmMvcGxhdC1heHMxMHgNCj4gwqBGOglhcmNoL2FyYy9ib290 -L2R0cy9heCoNCj4gwqBGOglEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvYXJjL2F4 -czEwKg0KPiDCoA0KPiArU1lOT1BTWVMgQVJDIFNEUCBjbG9jayBkcml2ZXINCj4gK006CVZsYWQg -WmFraGFyb3YgPHZ6YWtoYXJAc3lub3BzeXMuY29tPg0KPiArUzoJU3VwcG9ydGVkDQo+ICtGOglk -cml2ZXJzL2Nsay9heHMxMHgvKg0KPiArRjoJRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRp -bmdzL2Nsb2NrL3NucHMscGxsLWNsb2NrLnR4dA0KPiArDQo+IMKgU1lTVEVNIENPTkZJR1VSQVRJ -T04gKFNZU0NPTikNCj4gwqBNOglMZWUgSm9uZXMgPGxlZS5qb25lc0BsaW5hcm8ub3JnPg0KPiDC -oE06CUFybmQgQmVyZ21hbm4gPGFybmRAYXJuZGIuZGU+DQo+IGRpZmYgLS1naXQgYS9kcml2ZXJz -L2Nsay9heHMxMHgvTWFrZWZpbGUgYi9kcml2ZXJzL2Nsay9heHMxMHgvTWFrZWZpbGUNCj4gaW5k -ZXggMDE5OTZiOC4uZDc0N2RlYSAxMDA2NDQNCj4gLS0tIGEvZHJpdmVycy9jbGsvYXhzMTB4L01h -a2VmaWxlDQo+ICsrKyBiL2RyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZQ0KPiBAQCAtMSArMSwy -IEBADQo+IMKgb2JqLXkgKz0gaTJzX3BsbF9jbG9jay5vDQo+ICtvYmoteSArPSBwbGxfY2xvY2su -bw0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jIGIvZHJpdmVy -cy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+IGluZGV4 -IDAwMDAwMDAuLjc4NGEwYTINCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJzL2Nsay9h -eHMxMHgvcGxsX2Nsb2NrLmMNCj4gQEAgLTAsMCArMSwzODQgQEANCj4gKy8qDQo+ICsgKiBTeW5v -cHN5cyBBWFMxMFggU0RQIEdlbmVyaWMgUExMIGNsb2NrIGRyaXZlcg0KPiArICoNCj4gKyAqIENv -cHlyaWdodCAoQykgMjAxNyBTeW5vcHN5cw0KPiArICoNCj4gKyAqIFRoaXMgZmlsZSBpcyBsaWNl -bnNlZCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYw0KPiArICogTGlj -ZW5zZSB2ZXJzaW9uIDIuIFRoaXMgcHJvZ3JhbSBpcyBsaWNlbnNlZCAiYXMgaXMiIHdpdGhvdXQg -YW55DQo+ICsgKiB3YXJyYW50eSBvZiBhbnkga2luZCwgd2hldGhlciBleHByZXNzIG9yIGltcGxp -ZWQuDQo+ICsgKi8NCj4gKw0KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPg0K -PiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92 -aWRlci5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+DQo+ICsjaW5jbHVkZSA8bGludXgv -ZXJyLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ICsjaW5jbHVkZSA8bGludXgv -b2ZfYWRkcmVzcy5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPg0KPiArI2luY2x1 -ZGUgPGxpbnV4L3NsYWIuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPg0KPiArDQo+ICsvKiBQ -TEwgcmVnaXN0ZXJzIGFkZHJlc3NlcyAqLw0KPiArI2RlZmluZSBQTExfUkVHX0lESVYJMHgwDQo+ -ICsjZGVmaW5lIFBMTF9SRUdfRkJESVYJMHg0DQo+ICsjZGVmaW5lIFBMTF9SRUdfT0RJVgkweDgN -Cj4gKw0KPiArLyoNCj4gKyAqIEJpdCBmaWVsZHMgb2YgdGhlIFBMTCBJRElWL0ZCRElWL09ESVYg -cmVnaXN0ZXJzOg0KPiArICrCoMKgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f -X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQo+ICsgKiB8MzHCoMKgwqDCoMKg -wqDCoMKgwqDCoMKgwqDCoMKgwqDCoDE1fMKgwqDCoMKgMTTCoMKgwqDCoHzCoMKgwqAxM8KgwqDC -oHzCoMKgMTLCoMKgfDExwqDCoMKgwqDCoMKgwqDCoMKgNnw1wqDCoMKgwqDCoMKgwqDCoMKgMHwN -Cj4gKyAqIHwtLS0tLS0tUkVTUlZFRC0tLS0tLXwtTk9VUERBVEUtfC1CWVBBU1MtfC1FREdFLXwt -LUhJR0hUSU1FLS18LS1MT1dUSU1FLS18DQo+ICsgKiB8X19fX19fX19fX19fX19fX19fX198X19f -X19fX19fX3xfX19fX19fX3xfX19fX198X19fX19fX19fX19ffF9fX19fX19fX19ffA0KPiArICoN -Cj4gKyAqIEZvbGxvd2luZyBtYWNyb3MgZGV0aXJtaW5lIHRoZSB3YXkgb2YgYWNjZXNzIHRvIHRo -ZXNlIHJlZ2lzdGVycw0KPiArICogVGhleSBzaG91bGQgYmUgc2V0IHVwIG9ubHkgdXNpbmcgdGhl -IG1hY3Jvcy4NCj4gKyAqIHJlZyBzaG91bGQgYmUgYW5kIHVpbnQzMl90IHZhcmlhYmxlLg0KPiAr -ICovDQo+ICsNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTE9XKHJlZykJCQlcDQo+ICsJKCgocmVn -KSAmICgweDNGIDw8IDApKSA+PiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9ISUdIKHJlZykJ -CQlcDQo+ICsJKCgocmVnKSAmICgweDNGIDw8IDYpKSA+PiA2KQ0KPiArI2RlZmluZSBQTExfUkVH -X0dFVF9FREdFKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQoMTIpKSkgPyAxIDogMCkNCj4g -KyNkZWZpbmUgUExMX1JFR19HRVRfQllQQVNTKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQo -MTMpKSkgPyAxIDogMCkNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTk9VUEQocmVnKQkJCVwNCj4g -KwkoKChyZWcpICYgKEJJVCgxNCkpKSA/IDEgOiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9Q -QUQocmVnKQkJCVwNCj4gKwkoKChyZWcpICYgKDB4MUZGRkYgPDwgMTUpKSA+PiAxNSkNCj4gKw0K -PiArI2RlZmluZSBQTExfUkVHX1NFVF9MT1cocmVnLCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAo -KCh2YWx1ZSkgJiAweDNGKSA8PCAwKTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9ISUdIKHJl -ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDNGKSA8PCA2KTsgfQ0KPiAr -I2RlZmluZSBQTExfUkVHX1NFVF9FREdFKHJlZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2 -YWx1ZSkgJiAweDAxKSA8PCAxMik7IH0NCj4gKyNkZWZpbmUgUExMX1JFR19TRVRfQllQQVNTKHJl -ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDAxKSA8PCAxMyk7IH0NCj4g -KyNkZWZpbmUgUExMX1JFR19TRVRfTk9VUEQocmVnLCB2YWx1ZSkJXA0KPiArCXsgcmVnIHw9ICgo -KHZhbHVlKSAmIDB4MDEpIDw8IDE0KTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9QQUQocmVn -LCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDFGRkZGKSA8PCAxNSk7IH0N -Cj4gKw0KPiArI2RlZmluZSBQTExfTE9DSwkweDENCj4gKyNkZWZpbmUgUExMX01BWF9MT0NLX1RJ -TUUgMTAwIC8qIDEwMCB1cyAqLw0KPiArDQo+ICtzdHJ1Y3QgcGxsX2NmZyB7DQo+ICsJdTMyIHJh -dGU7DQo+ICsJdTMyIGlkaXY7DQo+ICsJdTMyIGZiZGl2Ow0KPiArCXUzMiBvZGl2Ow0KPiArfTsN -Cj4gKw0KPiArc3RydWN0IHBsbF9vZl90YWJsZSB7DQo+ICsJdW5zaWduZWQgbG9uZyBwcmF0ZTsN -Cj4gKwlzdHJ1Y3QgcGxsX2NmZyAqcGxsX2NmZ190YWJsZTsNCj4gK307DQo+ICsNCj4gK3N0cnVj -dCBwbGxfb2ZfZGF0YSB7DQo+ICsJc3RydWN0IHBsbF9vZl90YWJsZSAqcGxsX3RhYmxlOw0KPiAr -fTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2ZfZGF0YSBwZ3VfcGxsX2RhdGEgPSB7DQo+ -ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3RhYmxlIFtdKXsNCj4gKwkJew0KPiArCQkJ -LnByYXRlID0gMjcwMDAwMDAsDQo+ICsJCQkucGxsX2NmZ190YWJsZSA9IChzdHJ1Y3QgcGxsX2Nm -ZyBbXSl7DQo+ICsJCQkJeyAyNTIwMDAwMCwgMSwgODQsIDkwIH0sDQo+ICsJCQkJeyA1MDAwMDAw -MCwgMSwgMTAwLCA1NCB9LA0KPiArCQkJCXsgNzQyNTAwMDAsIDEsIDQ0LCAxNiB9LA0KPiArCQkJ -CXsgfSwNCj4gKwkJCX0sDQo+ICsJCX0sDQo+ICsJCS8qIFVzZWQgYXMgbGlzdCBsaW1pdGVyICov -DQo+ICsJCXsgfSwNCj4gKwl9LA0KPiArfTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2Zf -ZGF0YSBhcmNfcGxsX2RhdGEgPSB7DQo+ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3Rh -YmxlIFtdKXsNCj4gKwkJew0KPiArCQkJLnByYXRlID0gMzMzMzMzMzMsDQo+ICsJCQkucGxsX2Nm -Z190YWJsZSA9IChzdHJ1Y3QgcGxsX2NmZyBbXSl7DQo+ICsJCQkJeyAzMzMzMzMzMyzCoMKgMSwg -MSzCoMKgMSB9LA0KPiArCQkJCXsgNTAwMDAwMDAswqDCoDEsIDMwLCAyMCB9LA0KPiArCQkJCXsg -NzUwMDAwMDAswqDCoDIsIDQ1LCAxMCB9LA0KPiArCQkJCXsgOTAwMDAwMDAswqDCoDIsIDU0LCAx -MCB9LA0KPiArCQkJCXsgMTAwMDAwMDAwLCAxLCAzMCwgMTAgfSwNCj4gKwkJCQl7IDEyNTAwMDAw -MCwgMiwgNDUsIDYgfSwNCj4gKwkJCQl7IH0sDQo+ICsJCQl9LA0KPiArCQl9LA0KPiArCQkvKiBV -c2VkIGFzIGxpc3QgbGltaXRlciAqLw0KPiArCQl7IH0sDQo+ICsJfSwNCj4gK307DQo+ICsNCj4g -K3N0cnVjdCBwbGxfY2xrIHsNCj4gKwl2b2lkIF9faW9tZW0gKmJhc2U7DQo+ICsJdm9pZCBfX2lv -bWVtICpsb2NrOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfb2ZfZGF0YSAqcGxsX2RhdGE7DQo+ICsJ -c3RydWN0IGNsa19odyBodzsNCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7DQo+ICt9Ow0KPiArDQo+ -ICtzdGF0aWMgaW5saW5lIHZvaWQgcGxsX3dyaXRlKHN0cnVjdCBwbGxfY2xrICpjbGssIHVuc2ln -bmVkIGludCByZWcsDQo+ICsJCXVuc2lnbmVkIGludCB2YWwpDQo+ICt7DQo+ICsJaW93cml0ZTMy -KHZhbCwgY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiArc3RhdGljIGlubGluZSB1MzIg -cGxsX3JlYWQoc3RydWN0IHBsbF9jbGsgKmNsaywNCj4gKwkJdW5zaWduZWQgaW50IHJlZykNCj4g -K3sNCj4gKwlyZXR1cm4gaW9yZWFkMzIoY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiAr -c3RhdGljIGlubGluZSBzdHJ1Y3QgcGxsX2NsayAqdG9fcGxsX2NsayhzdHJ1Y3QgY2xrX2h3ICpo -dykNCj4gK3sNCj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGh3LCBzdHJ1Y3QgcGxsX2NsaywgaHcp -Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBkaXZfZ2V0X3ZhbHVlKHVuc2lnbmVk -IGludCByZWcpDQo+ICt7DQo+ICsJaWYgKFBMTF9SRUdfR0VUX0JZUEFTUyhyZWcpKQ0KPiArCQly -ZXR1cm4gMTsNCj4gKw0KPiArCXJldHVybiAoUExMX1JFR19HRVRfSElHSChyZWcpICsgUExMX1JF -R19HRVRfTE9XKHJlZykpOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBlbmNvZGVf -ZGl2KHVuc2lnbmVkIGludCBpZCwgaW50IHVwZCkNCj4gK3sNCj4gKwl1aW50MzJfdCBkaXYgPSAw -Ow0KPiArDQo+ICsJUExMX1JFR19TRVRfTE9XKGRpdiwgKGlkJTIgPT0gMCkgPyBpZCA+PiAxIDog -KGlkID4+IDEpICsgMSk7DQo+ICsJUExMX1JFR19TRVRfSElHSChkaXYsIGlkID4+IDEpOw0KPiAr -CVBMTF9SRUdfU0VUX0VER0UoZGl2LCBpZCUyKTsNCj4gKwlQTExfUkVHX1NFVF9CWVBBU1MoZGl2 -LCBpZCA9PSAxID8gMSA6IDApOw0KPiArCVBMTF9SRUdfU0VUX05PVVBEKGRpdiwgIXVwZCk7DQo+ -ICsNCj4gKwlyZXR1cm4gZGl2Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHBs -bF9jZmcgKnBsbF9nZXRfY2ZnKHVuc2lnbmVkIGxvbmcgcHJhdGUsDQo+ICsJCWNvbnN0IHN0cnVj -dCBwbGxfb2ZfdGFibGUgKnBsbF90YWJsZSkNCj4gK3sNCj4gKwlpbnQgaTsNCj4gKw0KPiArCWZv -ciAoaSA9IDA7IHBsbF90YWJsZVtpXS5wcmF0ZSAhPSAwOyBpKyspDQo+ICsJCWlmIChwbGxfdGFi -bGVbaV0ucHJhdGUgPT0gcHJhdGUpDQo+ICsJCQlyZXR1cm4gcGxsX3RhYmxlW2ldLnBsbF9jZmdf -dGFibGU7DQo+ICsNCj4gKwlyZXR1cm4gTlVMTDsNCj4gK30NCj4gKw0KPiArc3RhdGljIHVuc2ln -bmVkIGxvbmcgcGxsX3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LA0KPiArCQkJdW5zaWdu -ZWQgbG9uZyBwYXJlbnRfcmF0ZSkNCj4gK3sNCj4gKwl1NjQgcmF0ZTsNCj4gKwl1MzIgaWRpdiwg -ZmJkaXYsIG9kaXY7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcpOw0K -PiArDQo+ICsJaWRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0lESVYp -KTsNCj4gKwlmYmRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0ZCRElW -KSk7DQo+ICsJb2RpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX09ESVYp -KTsNCj4gKw0KPiArCXJhdGUgPSAodTY0KXBhcmVudF9yYXRlICogZmJkaXY7DQo+ICsJZG9fZGl2 -KHJhdGUsIGlkaXYgKiBvZGl2KTsNCj4gKw0KPiArCXJldHVybiAodW5zaWduZWQgbG9uZylyYXRl -Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgbG9uZyBwbGxfcm91bmRfcmF0ZShzdHJ1Y3QgY2xrX2h3 -ICpodywgdW5zaWduZWQgbG9uZyByYXRlLA0KPiArCQkJdW5zaWduZWQgbG9uZyAqcHJhdGUpDQo+ -ICt7DQo+ICsJaW50IGk7DQo+ICsJbG9uZyBiZXN0X3JhdGU7DQo+ICsJc3RydWN0IHBsbF9jbGsg -KmNsayA9IHRvX3BsbF9jbGsoaHcpOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2Zn -ID0gcGxsX2dldF9jZmcoKnByYXRlLA0KPiArCQkJY2xrLT5wbGxfZGF0YS0+cGxsX3RhYmxlKTsN -Cj4gKw0KPiArCWlmICghcGxsX2NmZykgew0KPiArCQlkZXZfZXJyKGNsay0+ZGV2LCAiaW52YWxp -ZCBwYXJlbnQgcmF0ZT0lbGRcbiIsICpwcmF0ZSk7DQo+ICsJCXJldHVybiAtRUlOVkFMOw0KPiAr -CX0NCj4gKw0KPiArCWlmIChwbGxfY2ZnWzBdLnJhdGUgPT0gMCkNCj4gKwkJcmV0dXJuIC1FSU5W -QUw7DQo+ICsNCj4gKwliZXN0X3JhdGUgPSBwbGxfY2ZnWzBdLnJhdGU7DQo+ICsNCj4gKwlmb3Ig -KGkgPSAxOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChhYnMocmF0ZSAt -IHBsbF9jZmdbaV0ucmF0ZSkgPCBhYnMocmF0ZSAtIGJlc3RfcmF0ZSkpDQo+ICsJCQliZXN0X3Jh -dGUgPSBwbGxfY2ZnW2ldLnJhdGU7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIGJlc3RfcmF0ZTsN -Cj4gK30NCj4gKw0KPiArc3RhdGljIGludCBwbGxfc2V0X3JhdGUoc3RydWN0IGNsa19odyAqaHcs -IHVuc2lnbmVkIGxvbmcgcmF0ZSwNCj4gKwkJCXVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpDQo+ -ICt7DQo+ICsJaW50IGk7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcp -Ow0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2ZnID0gcGxsX2dldF9jZmcocGFyZW50 -X3JhdGUsDQo+ICsJCQljbGstPnBsbF9kYXRhLT5wbGxfdGFibGUpOw0KPiArDQo+ICsJaWYgKCFw -bGxfY2ZnKSB7DQo+ICsJCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHBhcmVudCByYXRlPSVs -ZFxuIiwgcGFyZW50X3JhdGUpOw0KPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gKwl9DQo+ICsNCj4g -Kwlmb3IgKGkgPSAwOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChwbGxf -Y2ZnW2ldLnJhdGUgPT0gcmF0ZSkgew0KPiArCQkJcGxsX3dyaXRlKGNsaywgUExMX1JFR19JRElW -LA0KPiArCQkJCQllbmNvZGVfZGl2KHBsbF9jZmdbaV0uaWRpdiwgMCkpOw0KPiArCQkJcGxsX3dy -aXRlKGNsaywgUExMX1JFR19GQkRJViwNCj4gKwkJCQkJZW5jb2RlX2RpdihwbGxfY2ZnW2ldLmZi -ZGl2LCAwKSk7DQo+ICsJCQlwbGxfd3JpdGUoY2xrLCBQTExfUkVHX09ESVYsDQo+ICsJCQkJCWVu -Y29kZV9kaXYocGxsX2NmZ1tpXS5vZGl2LCAxKSk7DQo+ICsNCj4gKwkJCS8qDQo+ICsJCQnCoCog -V2FpdCB1bnRpbCBDR1UgcmVsb2Nrcy4NCj4gKwkJCcKgKiBJZiBhZnRlciB0aW1lb3V0IENHVSBp -cyB1bmxvY2tlZCB5ZXQgcmV0dXJuIGVycm9yDQo+ICsJCQnCoCovDQo+ICsJCQl1ZGVsYXkoUExM -X01BWF9MT0NLX1RJTUUpOw0KPiArCQkJaWYgKGlvcmVhZDMyKGNsay0+bG9jaykgJiBQTExfTE9D -SykNCj4gKwkJCQlyZXR1cm4gMDsNCj4gKwkJCWVsc2UNCj4gKwkJCQlyZXR1cm4gLUVUSU1FRE9V -VDsNCj4gKwkJfQ0KPiArCX0NCj4gKw0KPiArCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHJh -dGU9JWxkLCBwYXJlbnRfcmF0ZT0lbGRcbiIsIHJhdGUsDQo+ICsJCQlwYXJlbnRfcmF0ZSk7DQo+ -ICsJcmV0dXJuIC1FSU5WQUw7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY2xr -X29wcyBwbGxfb3BzID0gew0KPiArCS5yZWNhbGNfcmF0ZSA9IHBsbF9yZWNhbGNfcmF0ZSwNCj4g -Kwkucm91bmRfcmF0ZSA9IHBsbF9yb3VuZF9yYXRlLA0KPiArCS5zZXRfcmF0ZSA9IHBsbF9zZXRf -cmF0ZSwNCj4gK307DQo+ICsNCj4gK3N0YXRpYyBpbnQgcGxsX2Nsa19wcm9iZShzdHJ1Y3QgcGxh -dGZvcm1fZGV2aWNlICpwZGV2KQ0KPiArew0KPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2 -LT5kZXY7DQo+ICsJY29uc3QgY2hhciAqcGFyZW50X25hbWU7DQo+ICsJc3RydWN0IGNsayAqY2xr -Ow0KPiArCXN0cnVjdCBwbGxfY2xrICpwbGxfY2xrOw0KPiArCXN0cnVjdCByZXNvdXJjZSAqbWVt -Ow0KPiArCXN0cnVjdCBjbGtfaW5pdF9kYXRhIGluaXQgPSB7IH07DQo+ICsNCj4gKwlwbGxfY2xr -ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJ -aWYgKCFwbGxfY2xrKQ0KPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gKw0KPiArCW1lbSA9IHBsYXRm -b3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7DQo+ICsJcGxsX2Nsay0+ -YmFzZSA9IGRldm1faW9yZW1hcF9yZXNvdXJjZShkZXYsIG1lbSk7DQo+ICsJaWYgKElTX0VSUihw -bGxfY2xrLT5iYXNlKSkNCj4gKwkJcmV0dXJuIFBUUl9FUlIocGxsX2Nsay0+YmFzZSk7DQo+ICsN -Cj4gKwltZW0gPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDEp -Ow0KPiArCXBsbF9jbGstPmxvY2sgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCBtZW0pOw0K -PiArCWlmIChJU19FUlIocGxsX2Nsay0+bG9jaykpDQo+ICsJCXJldHVybiBQVFJfRVJSKHBsbF9j -bGstPmJhc2UpOw0KPiArDQo+ICsJaW5pdC5uYW1lID0gZGV2LT5vZl9ub2RlLT5uYW1lOw0KPiAr -CWluaXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVu -dF9uYW1lKGRldi0+b2Zfbm9kZSwgMCk7DQo+ICsJaW5pdC5wYXJlbnRfbmFtZXMgPSAmcGFyZW50 -X25hbWU7DQo+ICsJaW5pdC5udW1fcGFyZW50cyA9IDE7DQo+ICsJcGxsX2Nsay0+aHcuaW5pdCA9 -ICZpbml0Ow0KPiArCXBsbF9jbGstPmRldiA9IGRldjsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9 -IG9mX2RldmljZV9nZXRfbWF0Y2hfZGF0YShkZXYpOw0KPiArDQo+ICsJaWYgKCFwbGxfY2xrLT5w -bGxfZGF0YSkgew0KPiArCQlkZXZfZXJyKGRldiwgIk5vIE9GIG1hdGNoIGRhdGEgcHJvdmlkZWRc -biIpOw0KPiArCQkJcmV0dXJuIC1FSU5WQUw7DQo+ICsJfQ0KPiArDQo+ICsJY2xrID0gZGV2bV9j -bGtfcmVnaXN0ZXIoZGV2LCAmcGxsX2Nsay0+aHcpOw0KPiArCWlmIChJU19FUlIoY2xrKSkgew0K -PiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byByZWdpc3RlciAlcyBjbG9jayAoJWxkKVxuIiwN -Cj4gKwkJCQlpbml0Lm5hbWUsIFBUUl9FUlIoY2xrKSk7DQo+ICsJCXJldHVybiBQVFJfRVJSKGNs -ayk7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIG9mX2Nsa19hZGRfcHJvdmlkZXIoZGV2LT5vZl9u -b2RlLCBvZl9jbGtfc3JjX3NpbXBsZV9nZXQsIGNsayk7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBp -bnQgcGxsX2Nsa19yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gK3sNCj4g -KwlvZl9jbGtfZGVsX3Byb3ZpZGVyKHBkZXYtPmRldi5vZl9ub2RlKTsNCj4gKwlyZXR1cm4gMDsN -Cj4gK30NCj4gKw0KPiArc3RhdGljIHZvaWQgX19pbml0IG9mX3BsbF9jbGtfc2V0dXAoc3RydWN0 -IGRldmljZV9ub2RlICpub2RlKQ0KPiArew0KPiArCWNvbnN0IGNoYXIgKnBhcmVudF9uYW1lOw0K -PiArCXN0cnVjdCBjbGsgKmNsazsNCj4gKwlzdHJ1Y3QgcGxsX2NsayAqcGxsX2NsazsNCj4gKwlz -dHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0ID0geyB9Ow0KPiArDQo+ICsJcGxsX2NsayA9IGt6YWxs -b2Moc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJaWYgKCFwbGxfY2xrKQ0KPiAr -CQlyZXR1cm47DQo+ICsNCj4gKwlwbGxfY2xrLT5iYXNlID0gb2ZfaW9tYXAobm9kZSwgMCk7DQo+ -ICsJaWYgKCFwbGxfY2xrLT5iYXNlKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBwbGwg -ZGl2IHJlZ2lzdGVyc1xuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+YmFzZSk7DQo+ICsJCXJl -dHVybjsNCj4gKwl9DQo+ICsNCj4gKwlwbGxfY2xrLT5sb2NrID0gb2ZfaW9tYXAobm9kZSwgMSk7 -DQo+ICsJaWYgKCFwbGxfY2xrLT5sb2NrKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBw -bGwgbG9jayByZWdpc3RlclxuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+bG9jayk7DQo+ICsJ -CXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlpbml0Lm5hbWUgPSBub2RlLT5uYW1lOw0KPiArCWlu -aXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVudF9u -YW1lKG5vZGUsIDApOw0KPiArCWluaXQucGFyZW50X25hbWVzID0gJnBhcmVudF9uYW1lOw0KPiAr -CWluaXQubnVtX3BhcmVudHMgPSBwYXJlbnRfbmFtZSA/IDEgOiAwOw0KPiArCXBsbF9jbGstPmh3 -LmluaXQgPSAmaW5pdDsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9ICZhcmNfcGxsX2RhdGE7DQo+ -ICsNCj4gKwljbGsgPSBjbGtfcmVnaXN0ZXIoTlVMTCwgJnBsbF9jbGstPmh3KTsNCj4gKwlpZiAo -SVNfRVJSKGNsaykpIHsNCj4gKwkJcHJfZXJyKCJmYWlsZWQgdG8gcmVnaXN0ZXIgJXMgY2xvY2sg -KCVsZClcbiIsDQo+ICsJCQkJbm9kZS0+bmFtZSwgUFRSX0VSUihjbGspKTsNCj4gKwkJa2ZyZWUo -cGxsX2Nsayk7DQo+ICsJCXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlvZl9jbGtfYWRkX3Byb3Zp -ZGVyKG5vZGUsIG9mX2Nsa19zcmNfc2ltcGxlX2dldCwgY2xrKTsNCj4gK30NCj4gKw0KPiArQ0xL -X09GX0RFQ0xBUkUoYXhzMTB4X3BsbF9jbG9jaywgInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2si -LCBvZl9wbGxfY2xrX3NldHVwKTsNCj4gKw0KPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp -Y2VfaWQgcGxsX2Nsa19pZFtdID0gew0KPiArCXsgLmNvbXBhdGlibGUgPSAic25wcyxheHMxMHgt -YXJjLXBsbC1jbG9jayIsIC5kYXRhID0gJmFyY19wbGxfZGF0YX0sDQo+ICsJeyAuY29tcGF0aWJs -ZSA9ICJzbnBzLGF4czEweC1wZ3UtcGxsLWNsb2NrIiwgLmRhdGEgPSAmcGd1X3BsbF9kYXRhfSwN -Cj4gKwl7IH0sDQo+ICt9Ow0KPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgcGxsX2Nsa19pZCk7 -DQo+ICsNCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIHBsbF9jbGtfZHJpdmVyID0g -ew0KPiArCS5kcml2ZXIgPSB7DQo+ICsJCS5uYW1lID0gImF4czEweC1wbGwtY2xvY2siLA0KPiAr -CQkub2ZfbWF0Y2hfdGFibGUgPSBwbGxfY2xrX2lkLA0KPiArCX0sDQo+ICsJLnByb2JlID0gcGxs -X2Nsa19wcm9iZSwNCj4gKwkucmVtb3ZlID0gcGxsX2Nsa19yZW1vdmUsDQo+ICt9Ow0KPiArYnVp -bHRpbl9wbGF0Zm9ybV9kcml2ZXIocGxsX2Nsa19kcml2ZXIpOw0KPiArDQo+ICtNT0RVTEVfQVVU -SE9SKCJWbGFkIFpha2hhcm92IDx2emFraGFyQHN5bm9wc3lzLmNvbT4iKTsNCj4gK01PRFVMRV9E -RVNDUklQVElPTigiU3lub3BzeXMgQVhTMTBYIFNEUCBHZW5lcmljIFBMTCBDbG9jayBEcml2ZXIi -KTsNCj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsNCg0KTWF5YmUgeW91IGhhdmUgYW55IGNv -bW1lbnRzIG9yIHJlbWFya3MgYWJvdXQgdGhpcyBwYXRjaD8gQW5kIGlmIHlvdSBkb24ndCBjb3Vs -ZCB5b3UgcGxlYXNlIGFwcGx5IGl0Lg0KDQpUaGFua3MhDQoNCi0tIA0KQmVzdCByZWdhcmRzLA0K -VmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+ +Hi Michael, Stephen, + +On Tue, 2017-02-21@16:11 +0300, Vlad Zakharov wrote: +> AXS10X boards manages it's clocks using various PLLs. These PLL has same +> dividers and corresponding control registers mapped to different addresses. +> So we add one common driver for such PLLs. +> +> Each PLL on AXS10X board consist of three dividers: IDIV, FBDIV and +> ODIV. Output clock value is managed using these dividers. +> +> We add pre-defined tables with supported rate values and appropriate +> configurations of IDIV, FBDIV and ODIV for each value. +> +> As of today we add support for PLLs that generate clock for the +> following devices: +> ?* ARC core on AXC CPU tiles. +> ?* ARC PGU on ARC SDP Mainboard. +> and more to come later. +> +> Acked-by: Rob Herring <robh at kernel.org> +> Signed-off-by: Vlad Zakharov <vzakhar at synopsys.com> +> Signed-off-by: Jose Abreu <joabreu at synopsys.com> +> Cc: Michael Turquette <mturquette at baylibre.com> +> Cc: Stephen Boyd <sboyd at codeaurora.org> +> Cc: Mark Rutland <mark.rutland at arm.com> +> --- +> Cc: Rob Herring <robh at kernel.org> +> Changes v1..v2 +> ?- Replace '_' with '-' in device tree nodes +> +> ?.../devicetree/bindings/clock/snps,pll-clock.txt???|??28 ++ +> ?MAINTAINERS????????????????????????????????????????|???6 + +> ?drivers/clk/axs10x/Makefile????????????????????????|???1 + +> ?drivers/clk/axs10x/pll_clock.c?????????????????????| 384 +++++++++++++++++++++ +> ?4 files changed, 419 insertions(+) +> ?create mode 100644 Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> ?create mode 100644 drivers/clk/axs10x/pll_clock.c +> +> diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> new file mode 100644 +> index 0000000..5706246 +> --- /dev/null +> +++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> @@ -0,0 +1,28 @@ +> +Binding for the AXS10X Generic PLL clock +> + +> +This binding uses the common clock binding[1]. +> + +> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +> + +> +Required properties: +> +- compatible: should be "snps,axs10x-<name>-pll-clock" +> +??"snps,axs10x-arc-pll-clock" +> +??"snps,axs10x-pgu-pll-clock" +> +- reg: should always contain 2 pairs address - length: first for PLL config +> +registers and second for corresponding LOCK CGU register. +> +- clocks: shall be the input parent clock phandle for the PLL. +> +- #clock-cells: from common clock binding; Should always be set to 0. +> + +> +Example: +> + input-clk: input-clk { +> + clock-frequency = <33333333>; +> + compatible = "fixed-clock"; +> + #clock-cells = <0>; +> + }; +> + +> + core-clk: core-clk at 80 { +> + compatible = "snps,axs10x-arc-pll-clock"; +> + reg = <0x80 0x10 0x100 0x10>; +> + #clock-cells = <0>; +> + clocks = <&input-clk>; +> + }; +> diff --git a/MAINTAINERS b/MAINTAINERS +> index 3960e7f..5805833 100644 +> --- a/MAINTAINERS +> +++ b/MAINTAINERS +> @@ -11910,6 +11910,12 @@ F: arch/arc/plat-axs10x +> ?F: arch/arc/boot/dts/ax* +> ?F: Documentation/devicetree/bindings/arc/axs10* +> ? +> +SYNOPSYS ARC SDP clock driver +> +M: Vlad Zakharov <vzakhar at synopsys.com> +> +S: Supported +> +F: drivers/clk/axs10x/* +> +F: Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> + +> ?SYSTEM CONFIGURATION (SYSCON) +> ?M: Lee Jones <lee.jones at linaro.org> +> ?M: Arnd Bergmann <arnd at arndb.de> +> diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile +> index 01996b8..d747dea 100644 +> --- a/drivers/clk/axs10x/Makefile +> +++ b/drivers/clk/axs10x/Makefile +> @@ -1 +1,2 @@ +> ?obj-y += i2s_pll_clock.o +> +obj-y += pll_clock.o +> diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c +> new file mode 100644 +> index 0000000..784a0a2 +> --- /dev/null +> +++ b/drivers/clk/axs10x/pll_clock.c +> @@ -0,0 +1,384 @@ +> +/* +> + * Synopsys AXS10X SDP Generic PLL clock driver +> + * +> + * Copyright (C) 2017 Synopsys +> + * +> + * This file is licensed under the terms of the GNU General Public +> + * License version 2. This program is licensed "as is" without any +> + * warranty of any kind, whether express or implied. +> + */ +> + +> +#include <linux/platform_device.h> +> +#include <linux/module.h> +> +#include <linux/clk-provider.h> +> +#include <linux/delay.h> +> +#include <linux/err.h> +> +#include <linux/device.h> +> +#include <linux/of_address.h> +> +#include <linux/of_device.h> +> +#include <linux/slab.h> +> +#include <linux/of.h> +> + +> +/* PLL registers addresses */ +> +#define PLL_REG_IDIV 0x0 +> +#define PLL_REG_FBDIV 0x4 +> +#define PLL_REG_ODIV 0x8 +> + +> +/* +> + * Bit fields of the PLL IDIV/FBDIV/ODIV registers: +> + *??________________________________________________________________________ +> + * |31????????????????15|????14????|???13???|??12??|11?????????6|5?????????0| +> + * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--| +> + * |____________________|__________|________|______|____________|___________| +> + * +> + * Following macros detirmine the way of access to these registers +> + * They should be set up only using the macros. +> + * reg should be and uint32_t variable. +> + */ +> + +> +#define PLL_REG_GET_LOW(reg) \ +> + (((reg) & (0x3F << 0)) >> 0) +> +#define PLL_REG_GET_HIGH(reg) \ +> + (((reg) & (0x3F << 6)) >> 6) +> +#define PLL_REG_GET_EDGE(reg) \ +> + (((reg) & (BIT(12))) ? 1 : 0) +> +#define PLL_REG_GET_BYPASS(reg) \ +> + (((reg) & (BIT(13))) ? 1 : 0) +> +#define PLL_REG_GET_NOUPD(reg) \ +> + (((reg) & (BIT(14))) ? 1 : 0) +> +#define PLL_REG_GET_PAD(reg) \ +> + (((reg) & (0x1FFFF << 15)) >> 15) +> + +> +#define PLL_REG_SET_LOW(reg, value) \ +> + { reg |= (((value) & 0x3F) << 0); } +> +#define PLL_REG_SET_HIGH(reg, value) \ +> + { reg |= (((value) & 0x3F) << 6); } +> +#define PLL_REG_SET_EDGE(reg, value) \ +> + { reg |= (((value) & 0x01) << 12); } +> +#define PLL_REG_SET_BYPASS(reg, value) \ +> + { reg |= (((value) & 0x01) << 13); } +> +#define PLL_REG_SET_NOUPD(reg, value) \ +> + { reg |= (((value) & 0x01) << 14); } +> +#define PLL_REG_SET_PAD(reg, value) \ +> + { reg |= (((value) & 0x1FFFF) << 15); } +> + +> +#define PLL_LOCK 0x1 +> +#define PLL_MAX_LOCK_TIME 100 /* 100 us */ +> + +> +struct pll_cfg { +> + u32 rate; +> + u32 idiv; +> + u32 fbdiv; +> + u32 odiv; +> +}; +> + +> +struct pll_of_table { +> + unsigned long prate; +> + struct pll_cfg *pll_cfg_table; +> +}; +> + +> +struct pll_of_data { +> + struct pll_of_table *pll_table; +> +}; +> + +> +static struct pll_of_data pgu_pll_data = { +> + .pll_table = (struct pll_of_table []){ +> + { +> + .prate = 27000000, +> + .pll_cfg_table = (struct pll_cfg []){ +> + { 25200000, 1, 84, 90 }, +> + { 50000000, 1, 100, 54 }, +> + { 74250000, 1, 44, 16 }, +> + { }, +> + }, +> + }, +> + /* Used as list limiter */ +> + { }, +> + }, +> +}; +> + +> +static struct pll_of_data arc_pll_data = { +> + .pll_table = (struct pll_of_table []){ +> + { +> + .prate = 33333333, +> + .pll_cfg_table = (struct pll_cfg []){ +> + { 33333333,??1, 1,??1 }, +> + { 50000000,??1, 30, 20 }, +> + { 75000000,??2, 45, 10 }, +> + { 90000000,??2, 54, 10 }, +> + { 100000000, 1, 30, 10 }, +> + { 125000000, 2, 45, 6 }, +> + { }, +> + }, +> + }, +> + /* Used as list limiter */ +> + { }, +> + }, +> +}; +> + +> +struct pll_clk { +> + void __iomem *base; +> + void __iomem *lock; +> + const struct pll_of_data *pll_data; +> + struct clk_hw hw; +> + struct device *dev; +> +}; +> + +> +static inline void pll_write(struct pll_clk *clk, unsigned int reg, +> + unsigned int val) +> +{ +> + iowrite32(val, clk->base + reg); +> +} +> + +> +static inline u32 pll_read(struct pll_clk *clk, +> + unsigned int reg) +> +{ +> + return ioread32(clk->base + reg); +> +} +> + +> +static inline struct pll_clk *to_pll_clk(struct clk_hw *hw) +> +{ +> + return container_of(hw, struct pll_clk, hw); +> +} +> + +> +static inline u32 div_get_value(unsigned int reg) +> +{ +> + if (PLL_REG_GET_BYPASS(reg)) +> + return 1; +> + +> + return (PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg)); +> +} +> + +> +static inline u32 encode_div(unsigned int id, int upd) +> +{ +> + uint32_t div = 0; +> + +> + PLL_REG_SET_LOW(div, (id%2 == 0) ? id >> 1 : (id >> 1) + 1); +> + PLL_REG_SET_HIGH(div, id >> 1); +> + PLL_REG_SET_EDGE(div, id%2); +> + PLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0); +> + PLL_REG_SET_NOUPD(div, !upd); +> + +> + return div; +> +} +> + +> +static const struct pll_cfg *pll_get_cfg(unsigned long prate, +> + const struct pll_of_table *pll_table) +> +{ +> + int i; +> + +> + for (i = 0; pll_table[i].prate != 0; i++) +> + if (pll_table[i].prate == prate) +> + return pll_table[i].pll_cfg_table; +> + +> + return NULL; +> +} +> + +> +static unsigned long pll_recalc_rate(struct clk_hw *hw, +> + unsigned long parent_rate) +> +{ +> + u64 rate; +> + u32 idiv, fbdiv, odiv; +> + struct pll_clk *clk = to_pll_clk(hw); +> + +> + idiv = div_get_value(pll_read(clk, PLL_REG_IDIV)); +> + fbdiv = div_get_value(pll_read(clk, PLL_REG_FBDIV)); +> + odiv = div_get_value(pll_read(clk, PLL_REG_ODIV)); +> + +> + rate = (u64)parent_rate * fbdiv; +> + do_div(rate, idiv * odiv); +> + +> + return (unsigned long)rate; +> +} +> + +> +static long pll_round_rate(struct clk_hw *hw, unsigned long rate, +> + unsigned long *prate) +> +{ +> + int i; +> + long best_rate; +> + struct pll_clk *clk = to_pll_clk(hw); +> + const struct pll_cfg *pll_cfg = pll_get_cfg(*prate, +> + clk->pll_data->pll_table); +> + +> + if (!pll_cfg) { +> + dev_err(clk->dev, "invalid parent rate=%ld\n", *prate); +> + return -EINVAL; +> + } +> + +> + if (pll_cfg[0].rate == 0) +> + return -EINVAL; +> + +> + best_rate = pll_cfg[0].rate; +> + +> + for (i = 1; pll_cfg[i].rate != 0; i++) { +> + if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) +> + best_rate = pll_cfg[i].rate; +> + } +> + +> + return best_rate; +> +} +> + +> +static int pll_set_rate(struct clk_hw *hw, unsigned long rate, +> + unsigned long parent_rate) +> +{ +> + int i; +> + struct pll_clk *clk = to_pll_clk(hw); +> + const struct pll_cfg *pll_cfg = pll_get_cfg(parent_rate, +> + clk->pll_data->pll_table); +> + +> + if (!pll_cfg) { +> + dev_err(clk->dev, "invalid parent rate=%ld\n", parent_rate); +> + return -EINVAL; +> + } +> + +> + for (i = 0; pll_cfg[i].rate != 0; i++) { +> + if (pll_cfg[i].rate == rate) { +> + pll_write(clk, PLL_REG_IDIV, +> + encode_div(pll_cfg[i].idiv, 0)); +> + pll_write(clk, PLL_REG_FBDIV, +> + encode_div(pll_cfg[i].fbdiv, 0)); +> + pll_write(clk, PLL_REG_ODIV, +> + encode_div(pll_cfg[i].odiv, 1)); +> + +> + /* +> + ?* Wait until CGU relocks. +> + ?* If after timeout CGU is unlocked yet return error +> + ?*/ +> + udelay(PLL_MAX_LOCK_TIME); +> + if (ioread32(clk->lock) & PLL_LOCK) +> + return 0; +> + else +> + return -ETIMEDOUT; +> + } +> + } +> + +> + dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate, +> + parent_rate); +> + return -EINVAL; +> +} +> + +> +static const struct clk_ops pll_ops = { +> + .recalc_rate = pll_recalc_rate, +> + .round_rate = pll_round_rate, +> + .set_rate = pll_set_rate, +> +}; +> + +> +static int pll_clk_probe(struct platform_device *pdev) +> +{ +> + struct device *dev = &pdev->dev; +> + const char *parent_name; +> + struct clk *clk; +> + struct pll_clk *pll_clk; +> + struct resource *mem; +> + struct clk_init_data init = { }; +> + +> + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); +> + if (!pll_clk) +> + return -ENOMEM; +> + +> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +> + pll_clk->base = devm_ioremap_resource(dev, mem); +> + if (IS_ERR(pll_clk->base)) +> + return PTR_ERR(pll_clk->base); +> + +> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); +> + pll_clk->lock = devm_ioremap_resource(dev, mem); +> + if (IS_ERR(pll_clk->lock)) +> + return PTR_ERR(pll_clk->base); +> + +> + init.name = dev->of_node->name; +> + init.ops = &pll_ops; +> + parent_name = of_clk_get_parent_name(dev->of_node, 0); +> + init.parent_names = &parent_name; +> + init.num_parents = 1; +> + pll_clk->hw.init = &init; +> + pll_clk->dev = dev; +> + pll_clk->pll_data = of_device_get_match_data(dev); +> + +> + if (!pll_clk->pll_data) { +> + dev_err(dev, "No OF match data provided\n"); +> + return -EINVAL; +> + } +> + +> + clk = devm_clk_register(dev, &pll_clk->hw); +> + if (IS_ERR(clk)) { +> + dev_err(dev, "failed to register %s clock (%ld)\n", +> + init.name, PTR_ERR(clk)); +> + return PTR_ERR(clk); +> + } +> + +> + return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, clk); +> +} +> + +> +static int pll_clk_remove(struct platform_device *pdev) +> +{ +> + of_clk_del_provider(pdev->dev.of_node); +> + return 0; +> +} +> + +> +static void __init of_pll_clk_setup(struct device_node *node) +> +{ +> + const char *parent_name; +> + struct clk *clk; +> + struct pll_clk *pll_clk; +> + struct clk_init_data init = { }; +> + +> + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); +> + if (!pll_clk) +> + return; +> + +> + pll_clk->base = of_iomap(node, 0); +> + if (!pll_clk->base) { +> + pr_err("failed to map pll div registers\n"); +> + iounmap(pll_clk->base); +> + return; +> + } +> + +> + pll_clk->lock = of_iomap(node, 1); +> + if (!pll_clk->lock) { +> + pr_err("failed to map pll lock register\n"); +> + iounmap(pll_clk->lock); +> + return; +> + } +> + +> + init.name = node->name; +> + init.ops = &pll_ops; +> + parent_name = of_clk_get_parent_name(node, 0); +> + init.parent_names = &parent_name; +> + init.num_parents = parent_name ? 1 : 0; +> + pll_clk->hw.init = &init; +> + pll_clk->pll_data = &arc_pll_data; +> + +> + clk = clk_register(NULL, &pll_clk->hw); +> + if (IS_ERR(clk)) { +> + pr_err("failed to register %s clock (%ld)\n", +> + node->name, PTR_ERR(clk)); +> + kfree(pll_clk); +> + return; +> + } +> + +> + of_clk_add_provider(node, of_clk_src_simple_get, clk); +> +} +> + +> +CLK_OF_DECLARE(axs10x_pll_clock, "snps,axs10x-arc-pll-clock", of_pll_clk_setup); +> + +> +static const struct of_device_id pll_clk_id[] = { +> + { .compatible = "snps,axs10x-arc-pll-clock", .data = &arc_pll_data}, +> + { .compatible = "snps,axs10x-pgu-pll-clock", .data = &pgu_pll_data}, +> + { }, +> +}; +> +MODULE_DEVICE_TABLE(of, pll_clk_id); +> + +> +static struct platform_driver pll_clk_driver = { +> + .driver = { +> + .name = "axs10x-pll-clock", +> + .of_match_table = pll_clk_id, +> + }, +> + .probe = pll_clk_probe, +> + .remove = pll_clk_remove, +> +}; +> +builtin_platform_driver(pll_clk_driver); +> + +> +MODULE_AUTHOR("Vlad Zakharov <vzakhar at synopsys.com>"); +> +MODULE_DESCRIPTION("Synopsys AXS10X SDP Generic PLL Clock Driver"); +> +MODULE_LICENSE("GPL v2"); + +Maybe you have any comments or remarks about this patch? And if you don't could you please apply it. + +Thanks! + +-- +Best regards, +Vlad Zakharov <vzakhar at synopsys.com> diff --git a/a/content_digest b/N1/content_digest index e97820e..5361783 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,284 +1,504 @@ "ref\01487682670-4164-1-git-send-email-vzakhar@synopsys.com\0" - "From\0Vlad Zakharov <Vladislav.Zakharov@synopsys.com>\0" - "Subject\0Re: [PATCH v2] clk/axs10x: introduce AXS10X pll driver\0" + "From\0Vladislav.Zakharov@synopsys.com (Vlad Zakharov)\0" + "Subject\0[PATCH v2] clk/axs10x: introduce AXS10X pll driver\0" "Date\0Fri, 3 Mar 2017 13:18:34 +0000\0" - "To\0Michael Turquette <mturquette@baylibre.com>" - " Stephen Boyd <sboyd@codeaurora.org>\0" - "Cc\0linux-kernel@vger.kernel.org <linux-kernel@vger.kernel.org>" - mturquette@baylibre.com <mturquette@baylibre.com> - Jose Abreu <Jose.Abreu@synopsys.com> - devicetree@vger.kernel.org <devicetree@vger.kernel.org> - linux-snps-arc@lists.infradead.org <linux-snps-arc@lists.infradead.org> - mark.rutland@arm.com <mark.rutland@arm.com> - robh@kernel.org <robh@kernel.org> - linux-clk@vger.kernel.org <linux-clk@vger.kernel.org> - " sboyd@codeaurora.org <sboyd@codeaurora.org>\0" + "To\0linux-snps-arc@lists.infradead.org\0" "\00:1\0" "b\0" - "SGkgTWljaGFlbCwgU3RlcGhlbiwNCg0KT24gVHVlLCAyMDE3LTAyLTIxIGF0IDE2OjExICswMzAw\n" - "LCBWbGFkIFpha2hhcm92IHdyb3RlOg0KPiBBWFMxMFggYm9hcmRzIG1hbmFnZXMgaXQncyBjbG9j\n" - "a3MgdXNpbmcgdmFyaW91cyBQTExzLiBUaGVzZSBQTEwgaGFzIHNhbWUNCj4gZGl2aWRlcnMgYW5k\n" - "IGNvcnJlc3BvbmRpbmcgY29udHJvbCByZWdpc3RlcnMgbWFwcGVkIHRvIGRpZmZlcmVudCBhZGRy\n" - "ZXNzZXMuDQo+IFNvIHdlIGFkZCBvbmUgY29tbW9uIGRyaXZlciBmb3Igc3VjaCBQTExzLg0KPiAN\n" - "Cj4gRWFjaCBQTEwgb24gQVhTMTBYIGJvYXJkIGNvbnNpc3Qgb2YgdGhyZWUgZGl2aWRlcnM6IElE\n" - "SVYsIEZCRElWIGFuZA0KPiBPRElWLiBPdXRwdXQgY2xvY2sgdmFsdWUgaXMgbWFuYWdlZCB1c2lu\n" - "ZyB0aGVzZSBkaXZpZGVycy4NCj4gDQo+IFdlIGFkZCBwcmUtZGVmaW5lZCB0YWJsZXMgd2l0aCBz\n" - "dXBwb3J0ZWQgcmF0ZSB2YWx1ZXMgYW5kIGFwcHJvcHJpYXRlDQo+IGNvbmZpZ3VyYXRpb25zIG9m\n" - "IElESVYsIEZCRElWIGFuZCBPRElWIGZvciBlYWNoIHZhbHVlLg0KPiANCj4gQXMgb2YgdG9kYXkg\n" - "d2UgYWRkIHN1cHBvcnQgZm9yIFBMTHMgdGhhdCBnZW5lcmF0ZSBjbG9jayBmb3IgdGhlDQo+IGZv\n" - "bGxvd2luZyBkZXZpY2VzOg0KPiDCoCogQVJDIGNvcmUgb24gQVhDIENQVSB0aWxlcy4NCj4gwqAq\n" - "IEFSQyBQR1Ugb24gQVJDIFNEUCBNYWluYm9hcmQuDQo+IGFuZCBtb3JlIHRvIGNvbWUgbGF0ZXIu\n" - "DQo+IA0KPiBBY2tlZC1ieTogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gU2lnbmVk\n" - "LW9mZi1ieTogVmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+DQo+IFNpZ25lZC1v\n" - "ZmYtYnk6IEpvc2UgQWJyZXUgPGpvYWJyZXVAc3lub3BzeXMuY29tPg0KPiBDYzogTWljaGFlbCBU\n" - "dXJxdWV0dGUgPG10dXJxdWV0dGVAYmF5bGlicmUuY29tPg0KPiBDYzogU3RlcGhlbiBCb3lkIDxz\n" - "Ym95ZEBjb2RlYXVyb3JhLm9yZz4NCj4gQ2M6IE1hcmsgUnV0bGFuZCA8bWFyay5ydXRsYW5kQGFy\n" - "bS5jb20+DQo+IC0tLQ0KPiBDYzogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gQ2hh\n" - "bmdlcyB2MS4udjINCj4gwqAtIFJlcGxhY2UgJ18nIHdpdGggJy0nIGluIGRldmljZSB0cmVlIG5v\n" - "ZGVzDQo+IA0KPiDCoC4uLi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxsLWNsb2Nr\n" - "LnR4dMKgwqDCoHzCoMKgMjggKysNCj4gwqBNQUlOVEFJTkVSU8KgwqDCoMKgwqDCoMKgwqDCoMKg\n" - "wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC\n" - "oMKgfMKgwqDCoDYgKw0KPiDCoGRyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZcKgwqDCoMKgwqDC\n" - "oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAxICsNCj4gwqBkcml2\n" - "ZXJzL2Nsay9heHMxMHgvcGxsX2Nsb2NrLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC\n" - "oMKgwqDCoMKgwqB8IDM4NCArKysrKysrKysrKysrKysrKysrKysNCj4gwqA0IGZpbGVzIGNoYW5n\n" - "ZWQsIDQxOSBpbnNlcnRpb25zKCspDQo+IMKgY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp\n" - "b24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gwqBjcmVh\n" - "dGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IA0KPiBkaWZm\n" - "IC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxs\n" - "LWNsb2NrLnR4dA0KPiBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9z\n" - "bnBzLHBsbC1jbG9jay50eHQNCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gaW5kZXggMDAwMDAw\n" - "MC4uNTcwNjI0Ng0KPiAtLS0gL2Rldi9udWxsDQo+ICsrKyBiL0RvY3VtZW50YXRpb24vZGV2aWNl\n" - "dHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gQEAgLTAsMCArMSwyOCBA\n" - "QA0KPiArQmluZGluZyBmb3IgdGhlIEFYUzEwWCBHZW5lcmljIFBMTCBjbG9jaw0KPiArDQo+ICtU\n" - "aGlzIGJpbmRpbmcgdXNlcyB0aGUgY29tbW9uIGNsb2NrIGJpbmRpbmdbMV0uDQo+ICsNCj4gK1sx\n" - "XSBEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvY2xvY2svY2xvY2stYmluZGluZ3Mu\n" - "dHh0DQo+ICsNCj4gK1JlcXVpcmVkIHByb3BlcnRpZXM6DQo+ICstIGNvbXBhdGlibGU6IHNob3Vs\n" - "ZCBiZSAic25wcyxheHMxMHgtPG5hbWU+LXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgt\n" - "YXJjLXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgtcGd1LXBsbC1jbG9jayINCj4gKy0g\n" - "cmVnOiBzaG91bGQgYWx3YXlzIGNvbnRhaW4gMiBwYWlycyBhZGRyZXNzIC0gbGVuZ3RoOiBmaXJz\n" - "dCBmb3IgUExMIGNvbmZpZw0KPiArcmVnaXN0ZXJzIGFuZCBzZWNvbmQgZm9yIGNvcnJlc3BvbmRp\n" - "bmcgTE9DSyBDR1UgcmVnaXN0ZXIuDQo+ICstIGNsb2Nrczogc2hhbGwgYmUgdGhlIGlucHV0IHBh\n" - "cmVudCBjbG9jayBwaGFuZGxlIGZvciB0aGUgUExMLg0KPiArLSAjY2xvY2stY2VsbHM6IGZyb20g\n" - "Y29tbW9uIGNsb2NrIGJpbmRpbmc7IFNob3VsZCBhbHdheXMgYmUgc2V0IHRvIDAuDQo+ICsNCj4g\n" - "K0V4YW1wbGU6DQo+ICsJaW5wdXQtY2xrOiBpbnB1dC1jbGsgew0KPiArCQljbG9jay1mcmVxdWVu\n" - "Y3kgPSA8MzMzMzMzMzM+Ow0KPiArCQljb21wYXRpYmxlID0gImZpeGVkLWNsb2NrIjsNCj4gKwkJ\n" - "I2Nsb2NrLWNlbGxzID0gPDA+Ow0KPiArCX07DQo+ICsNCj4gKwljb3JlLWNsazogY29yZS1jbGtA\n" - "ODAgew0KPiArCQljb21wYXRpYmxlID0gInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2siOw0KPiAr\n" - "CQlyZWcgPSA8MHg4MCAweDEwIDB4MTAwIDB4MTA+Ow0KPiArCQkjY2xvY2stY2VsbHMgPSA8MD47\n" - "DQo+ICsJCWNsb2NrcyA9IDwmaW5wdXQtY2xrPjsNCj4gKwl9Ow0KPiBkaWZmIC0tZ2l0IGEvTUFJ\n" - "TlRBSU5FUlMgYi9NQUlOVEFJTkVSUw0KPiBpbmRleCAzOTYwZTdmLi41ODA1ODMzIDEwMDY0NA0K\n" - "PiAtLS0gYS9NQUlOVEFJTkVSUw0KPiArKysgYi9NQUlOVEFJTkVSUw0KPiBAQCAtMTE5MTAsNiAr\n" - "MTE5MTAsMTIgQEAgRjoJYXJjaC9hcmMvcGxhdC1heHMxMHgNCj4gwqBGOglhcmNoL2FyYy9ib290\n" - "L2R0cy9heCoNCj4gwqBGOglEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvYXJjL2F4\n" - "czEwKg0KPiDCoA0KPiArU1lOT1BTWVMgQVJDIFNEUCBjbG9jayBkcml2ZXINCj4gK006CVZsYWQg\n" - "WmFraGFyb3YgPHZ6YWtoYXJAc3lub3BzeXMuY29tPg0KPiArUzoJU3VwcG9ydGVkDQo+ICtGOglk\n" - "cml2ZXJzL2Nsay9heHMxMHgvKg0KPiArRjoJRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRp\n" - "bmdzL2Nsb2NrL3NucHMscGxsLWNsb2NrLnR4dA0KPiArDQo+IMKgU1lTVEVNIENPTkZJR1VSQVRJ\n" - "T04gKFNZU0NPTikNCj4gwqBNOglMZWUgSm9uZXMgPGxlZS5qb25lc0BsaW5hcm8ub3JnPg0KPiDC\n" - "oE06CUFybmQgQmVyZ21hbm4gPGFybmRAYXJuZGIuZGU+DQo+IGRpZmYgLS1naXQgYS9kcml2ZXJz\n" - "L2Nsay9heHMxMHgvTWFrZWZpbGUgYi9kcml2ZXJzL2Nsay9heHMxMHgvTWFrZWZpbGUNCj4gaW5k\n" - "ZXggMDE5OTZiOC4uZDc0N2RlYSAxMDA2NDQNCj4gLS0tIGEvZHJpdmVycy9jbGsvYXhzMTB4L01h\n" - "a2VmaWxlDQo+ICsrKyBiL2RyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZQ0KPiBAQCAtMSArMSwy\n" - "IEBADQo+IMKgb2JqLXkgKz0gaTJzX3BsbF9jbG9jay5vDQo+ICtvYmoteSArPSBwbGxfY2xvY2su\n" - "bw0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jIGIvZHJpdmVy\n" - "cy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+IGluZGV4\n" - "IDAwMDAwMDAuLjc4NGEwYTINCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJzL2Nsay9h\n" - "eHMxMHgvcGxsX2Nsb2NrLmMNCj4gQEAgLTAsMCArMSwzODQgQEANCj4gKy8qDQo+ICsgKiBTeW5v\n" - "cHN5cyBBWFMxMFggU0RQIEdlbmVyaWMgUExMIGNsb2NrIGRyaXZlcg0KPiArICoNCj4gKyAqIENv\n" - "cHlyaWdodCAoQykgMjAxNyBTeW5vcHN5cw0KPiArICoNCj4gKyAqIFRoaXMgZmlsZSBpcyBsaWNl\n" - "bnNlZCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYw0KPiArICogTGlj\n" - "ZW5zZSB2ZXJzaW9uIDIuIFRoaXMgcHJvZ3JhbSBpcyBsaWNlbnNlZCAiYXMgaXMiIHdpdGhvdXQg\n" - "YW55DQo+ICsgKiB3YXJyYW50eSBvZiBhbnkga2luZCwgd2hldGhlciBleHByZXNzIG9yIGltcGxp\n" - "ZWQuDQo+ICsgKi8NCj4gKw0KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPg0K\n" - "PiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92\n" - "aWRlci5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+DQo+ICsjaW5jbHVkZSA8bGludXgv\n" - "ZXJyLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ICsjaW5jbHVkZSA8bGludXgv\n" - "b2ZfYWRkcmVzcy5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPg0KPiArI2luY2x1\n" - "ZGUgPGxpbnV4L3NsYWIuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPg0KPiArDQo+ICsvKiBQ\n" - "TEwgcmVnaXN0ZXJzIGFkZHJlc3NlcyAqLw0KPiArI2RlZmluZSBQTExfUkVHX0lESVYJMHgwDQo+\n" - "ICsjZGVmaW5lIFBMTF9SRUdfRkJESVYJMHg0DQo+ICsjZGVmaW5lIFBMTF9SRUdfT0RJVgkweDgN\n" - "Cj4gKw0KPiArLyoNCj4gKyAqIEJpdCBmaWVsZHMgb2YgdGhlIFBMTCBJRElWL0ZCRElWL09ESVYg\n" - "cmVnaXN0ZXJzOg0KPiArICrCoMKgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f\n" - "X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQo+ICsgKiB8MzHCoMKgwqDCoMKg\n" - "wqDCoMKgwqDCoMKgwqDCoMKgwqDCoDE1fMKgwqDCoMKgMTTCoMKgwqDCoHzCoMKgwqAxM8KgwqDC\n" - "oHzCoMKgMTLCoMKgfDExwqDCoMKgwqDCoMKgwqDCoMKgNnw1wqDCoMKgwqDCoMKgwqDCoMKgMHwN\n" - "Cj4gKyAqIHwtLS0tLS0tUkVTUlZFRC0tLS0tLXwtTk9VUERBVEUtfC1CWVBBU1MtfC1FREdFLXwt\n" - "LUhJR0hUSU1FLS18LS1MT1dUSU1FLS18DQo+ICsgKiB8X19fX19fX19fX19fX19fX19fX198X19f\n" - "X19fX19fX3xfX19fX19fX3xfX19fX198X19fX19fX19fX19ffF9fX19fX19fX19ffA0KPiArICoN\n" - "Cj4gKyAqIEZvbGxvd2luZyBtYWNyb3MgZGV0aXJtaW5lIHRoZSB3YXkgb2YgYWNjZXNzIHRvIHRo\n" - "ZXNlIHJlZ2lzdGVycw0KPiArICogVGhleSBzaG91bGQgYmUgc2V0IHVwIG9ubHkgdXNpbmcgdGhl\n" - "IG1hY3Jvcy4NCj4gKyAqIHJlZyBzaG91bGQgYmUgYW5kIHVpbnQzMl90IHZhcmlhYmxlLg0KPiAr\n" - "ICovDQo+ICsNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTE9XKHJlZykJCQlcDQo+ICsJKCgocmVn\n" - "KSAmICgweDNGIDw8IDApKSA+PiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9ISUdIKHJlZykJ\n" - "CQlcDQo+ICsJKCgocmVnKSAmICgweDNGIDw8IDYpKSA+PiA2KQ0KPiArI2RlZmluZSBQTExfUkVH\n" - "X0dFVF9FREdFKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQoMTIpKSkgPyAxIDogMCkNCj4g\n" - "KyNkZWZpbmUgUExMX1JFR19HRVRfQllQQVNTKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQo\n" - "MTMpKSkgPyAxIDogMCkNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTk9VUEQocmVnKQkJCVwNCj4g\n" - "KwkoKChyZWcpICYgKEJJVCgxNCkpKSA/IDEgOiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9Q\n" - "QUQocmVnKQkJCVwNCj4gKwkoKChyZWcpICYgKDB4MUZGRkYgPDwgMTUpKSA+PiAxNSkNCj4gKw0K\n" - "PiArI2RlZmluZSBQTExfUkVHX1NFVF9MT1cocmVnLCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAo\n" - "KCh2YWx1ZSkgJiAweDNGKSA8PCAwKTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9ISUdIKHJl\n" - "ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDNGKSA8PCA2KTsgfQ0KPiAr\n" - "I2RlZmluZSBQTExfUkVHX1NFVF9FREdFKHJlZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2\n" - "YWx1ZSkgJiAweDAxKSA8PCAxMik7IH0NCj4gKyNkZWZpbmUgUExMX1JFR19TRVRfQllQQVNTKHJl\n" - "ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDAxKSA8PCAxMyk7IH0NCj4g\n" - "KyNkZWZpbmUgUExMX1JFR19TRVRfTk9VUEQocmVnLCB2YWx1ZSkJXA0KPiArCXsgcmVnIHw9ICgo\n" - "KHZhbHVlKSAmIDB4MDEpIDw8IDE0KTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9QQUQocmVn\n" - "LCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDFGRkZGKSA8PCAxNSk7IH0N\n" - "Cj4gKw0KPiArI2RlZmluZSBQTExfTE9DSwkweDENCj4gKyNkZWZpbmUgUExMX01BWF9MT0NLX1RJ\n" - "TUUgMTAwIC8qIDEwMCB1cyAqLw0KPiArDQo+ICtzdHJ1Y3QgcGxsX2NmZyB7DQo+ICsJdTMyIHJh\n" - "dGU7DQo+ICsJdTMyIGlkaXY7DQo+ICsJdTMyIGZiZGl2Ow0KPiArCXUzMiBvZGl2Ow0KPiArfTsN\n" - "Cj4gKw0KPiArc3RydWN0IHBsbF9vZl90YWJsZSB7DQo+ICsJdW5zaWduZWQgbG9uZyBwcmF0ZTsN\n" - "Cj4gKwlzdHJ1Y3QgcGxsX2NmZyAqcGxsX2NmZ190YWJsZTsNCj4gK307DQo+ICsNCj4gK3N0cnVj\n" - "dCBwbGxfb2ZfZGF0YSB7DQo+ICsJc3RydWN0IHBsbF9vZl90YWJsZSAqcGxsX3RhYmxlOw0KPiAr\n" - "fTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2ZfZGF0YSBwZ3VfcGxsX2RhdGEgPSB7DQo+\n" - "ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3RhYmxlIFtdKXsNCj4gKwkJew0KPiArCQkJ\n" - "LnByYXRlID0gMjcwMDAwMDAsDQo+ICsJCQkucGxsX2NmZ190YWJsZSA9IChzdHJ1Y3QgcGxsX2Nm\n" - "ZyBbXSl7DQo+ICsJCQkJeyAyNTIwMDAwMCwgMSwgODQsIDkwIH0sDQo+ICsJCQkJeyA1MDAwMDAw\n" - "MCwgMSwgMTAwLCA1NCB9LA0KPiArCQkJCXsgNzQyNTAwMDAsIDEsIDQ0LCAxNiB9LA0KPiArCQkJ\n" - "CXsgfSwNCj4gKwkJCX0sDQo+ICsJCX0sDQo+ICsJCS8qIFVzZWQgYXMgbGlzdCBsaW1pdGVyICov\n" - "DQo+ICsJCXsgfSwNCj4gKwl9LA0KPiArfTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2Zf\n" - "ZGF0YSBhcmNfcGxsX2RhdGEgPSB7DQo+ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3Rh\n" - "YmxlIFtdKXsNCj4gKwkJew0KPiArCQkJLnByYXRlID0gMzMzMzMzMzMsDQo+ICsJCQkucGxsX2Nm\n" - "Z190YWJsZSA9IChzdHJ1Y3QgcGxsX2NmZyBbXSl7DQo+ICsJCQkJeyAzMzMzMzMzMyzCoMKgMSwg\n" - "MSzCoMKgMSB9LA0KPiArCQkJCXsgNTAwMDAwMDAswqDCoDEsIDMwLCAyMCB9LA0KPiArCQkJCXsg\n" - "NzUwMDAwMDAswqDCoDIsIDQ1LCAxMCB9LA0KPiArCQkJCXsgOTAwMDAwMDAswqDCoDIsIDU0LCAx\n" - "MCB9LA0KPiArCQkJCXsgMTAwMDAwMDAwLCAxLCAzMCwgMTAgfSwNCj4gKwkJCQl7IDEyNTAwMDAw\n" - "MCwgMiwgNDUsIDYgfSwNCj4gKwkJCQl7IH0sDQo+ICsJCQl9LA0KPiArCQl9LA0KPiArCQkvKiBV\n" - "c2VkIGFzIGxpc3QgbGltaXRlciAqLw0KPiArCQl7IH0sDQo+ICsJfSwNCj4gK307DQo+ICsNCj4g\n" - "K3N0cnVjdCBwbGxfY2xrIHsNCj4gKwl2b2lkIF9faW9tZW0gKmJhc2U7DQo+ICsJdm9pZCBfX2lv\n" - "bWVtICpsb2NrOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfb2ZfZGF0YSAqcGxsX2RhdGE7DQo+ICsJ\n" - "c3RydWN0IGNsa19odyBodzsNCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7DQo+ICt9Ow0KPiArDQo+\n" - "ICtzdGF0aWMgaW5saW5lIHZvaWQgcGxsX3dyaXRlKHN0cnVjdCBwbGxfY2xrICpjbGssIHVuc2ln\n" - "bmVkIGludCByZWcsDQo+ICsJCXVuc2lnbmVkIGludCB2YWwpDQo+ICt7DQo+ICsJaW93cml0ZTMy\n" - "KHZhbCwgY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiArc3RhdGljIGlubGluZSB1MzIg\n" - "cGxsX3JlYWQoc3RydWN0IHBsbF9jbGsgKmNsaywNCj4gKwkJdW5zaWduZWQgaW50IHJlZykNCj4g\n" - "K3sNCj4gKwlyZXR1cm4gaW9yZWFkMzIoY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiAr\n" - "c3RhdGljIGlubGluZSBzdHJ1Y3QgcGxsX2NsayAqdG9fcGxsX2NsayhzdHJ1Y3QgY2xrX2h3ICpo\n" - "dykNCj4gK3sNCj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGh3LCBzdHJ1Y3QgcGxsX2NsaywgaHcp\n" - "Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBkaXZfZ2V0X3ZhbHVlKHVuc2lnbmVk\n" - "IGludCByZWcpDQo+ICt7DQo+ICsJaWYgKFBMTF9SRUdfR0VUX0JZUEFTUyhyZWcpKQ0KPiArCQly\n" - "ZXR1cm4gMTsNCj4gKw0KPiArCXJldHVybiAoUExMX1JFR19HRVRfSElHSChyZWcpICsgUExMX1JF\n" - "R19HRVRfTE9XKHJlZykpOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBlbmNvZGVf\n" - "ZGl2KHVuc2lnbmVkIGludCBpZCwgaW50IHVwZCkNCj4gK3sNCj4gKwl1aW50MzJfdCBkaXYgPSAw\n" - "Ow0KPiArDQo+ICsJUExMX1JFR19TRVRfTE9XKGRpdiwgKGlkJTIgPT0gMCkgPyBpZCA+PiAxIDog\n" - "KGlkID4+IDEpICsgMSk7DQo+ICsJUExMX1JFR19TRVRfSElHSChkaXYsIGlkID4+IDEpOw0KPiAr\n" - "CVBMTF9SRUdfU0VUX0VER0UoZGl2LCBpZCUyKTsNCj4gKwlQTExfUkVHX1NFVF9CWVBBU1MoZGl2\n" - "LCBpZCA9PSAxID8gMSA6IDApOw0KPiArCVBMTF9SRUdfU0VUX05PVVBEKGRpdiwgIXVwZCk7DQo+\n" - "ICsNCj4gKwlyZXR1cm4gZGl2Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHBs\n" - "bF9jZmcgKnBsbF9nZXRfY2ZnKHVuc2lnbmVkIGxvbmcgcHJhdGUsDQo+ICsJCWNvbnN0IHN0cnVj\n" - "dCBwbGxfb2ZfdGFibGUgKnBsbF90YWJsZSkNCj4gK3sNCj4gKwlpbnQgaTsNCj4gKw0KPiArCWZv\n" - "ciAoaSA9IDA7IHBsbF90YWJsZVtpXS5wcmF0ZSAhPSAwOyBpKyspDQo+ICsJCWlmIChwbGxfdGFi\n" - "bGVbaV0ucHJhdGUgPT0gcHJhdGUpDQo+ICsJCQlyZXR1cm4gcGxsX3RhYmxlW2ldLnBsbF9jZmdf\n" - "dGFibGU7DQo+ICsNCj4gKwlyZXR1cm4gTlVMTDsNCj4gK30NCj4gKw0KPiArc3RhdGljIHVuc2ln\n" - "bmVkIGxvbmcgcGxsX3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LA0KPiArCQkJdW5zaWdu\n" - "ZWQgbG9uZyBwYXJlbnRfcmF0ZSkNCj4gK3sNCj4gKwl1NjQgcmF0ZTsNCj4gKwl1MzIgaWRpdiwg\n" - "ZmJkaXYsIG9kaXY7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcpOw0K\n" - "PiArDQo+ICsJaWRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0lESVYp\n" - "KTsNCj4gKwlmYmRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0ZCRElW\n" - "KSk7DQo+ICsJb2RpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX09ESVYp\n" - "KTsNCj4gKw0KPiArCXJhdGUgPSAodTY0KXBhcmVudF9yYXRlICogZmJkaXY7DQo+ICsJZG9fZGl2\n" - "KHJhdGUsIGlkaXYgKiBvZGl2KTsNCj4gKw0KPiArCXJldHVybiAodW5zaWduZWQgbG9uZylyYXRl\n" - "Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgbG9uZyBwbGxfcm91bmRfcmF0ZShzdHJ1Y3QgY2xrX2h3\n" - "ICpodywgdW5zaWduZWQgbG9uZyByYXRlLA0KPiArCQkJdW5zaWduZWQgbG9uZyAqcHJhdGUpDQo+\n" - "ICt7DQo+ICsJaW50IGk7DQo+ICsJbG9uZyBiZXN0X3JhdGU7DQo+ICsJc3RydWN0IHBsbF9jbGsg\n" - "KmNsayA9IHRvX3BsbF9jbGsoaHcpOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2Zn\n" - "ID0gcGxsX2dldF9jZmcoKnByYXRlLA0KPiArCQkJY2xrLT5wbGxfZGF0YS0+cGxsX3RhYmxlKTsN\n" - "Cj4gKw0KPiArCWlmICghcGxsX2NmZykgew0KPiArCQlkZXZfZXJyKGNsay0+ZGV2LCAiaW52YWxp\n" - "ZCBwYXJlbnQgcmF0ZT0lbGRcbiIsICpwcmF0ZSk7DQo+ICsJCXJldHVybiAtRUlOVkFMOw0KPiAr\n" - "CX0NCj4gKw0KPiArCWlmIChwbGxfY2ZnWzBdLnJhdGUgPT0gMCkNCj4gKwkJcmV0dXJuIC1FSU5W\n" - "QUw7DQo+ICsNCj4gKwliZXN0X3JhdGUgPSBwbGxfY2ZnWzBdLnJhdGU7DQo+ICsNCj4gKwlmb3Ig\n" - "KGkgPSAxOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChhYnMocmF0ZSAt\n" - "IHBsbF9jZmdbaV0ucmF0ZSkgPCBhYnMocmF0ZSAtIGJlc3RfcmF0ZSkpDQo+ICsJCQliZXN0X3Jh\n" - "dGUgPSBwbGxfY2ZnW2ldLnJhdGU7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIGJlc3RfcmF0ZTsN\n" - "Cj4gK30NCj4gKw0KPiArc3RhdGljIGludCBwbGxfc2V0X3JhdGUoc3RydWN0IGNsa19odyAqaHcs\n" - "IHVuc2lnbmVkIGxvbmcgcmF0ZSwNCj4gKwkJCXVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpDQo+\n" - "ICt7DQo+ICsJaW50IGk7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcp\n" - "Ow0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2ZnID0gcGxsX2dldF9jZmcocGFyZW50\n" - "X3JhdGUsDQo+ICsJCQljbGstPnBsbF9kYXRhLT5wbGxfdGFibGUpOw0KPiArDQo+ICsJaWYgKCFw\n" - "bGxfY2ZnKSB7DQo+ICsJCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHBhcmVudCByYXRlPSVs\n" - "ZFxuIiwgcGFyZW50X3JhdGUpOw0KPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gKwl9DQo+ICsNCj4g\n" - "Kwlmb3IgKGkgPSAwOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChwbGxf\n" - "Y2ZnW2ldLnJhdGUgPT0gcmF0ZSkgew0KPiArCQkJcGxsX3dyaXRlKGNsaywgUExMX1JFR19JRElW\n" - "LA0KPiArCQkJCQllbmNvZGVfZGl2KHBsbF9jZmdbaV0uaWRpdiwgMCkpOw0KPiArCQkJcGxsX3dy\n" - "aXRlKGNsaywgUExMX1JFR19GQkRJViwNCj4gKwkJCQkJZW5jb2RlX2RpdihwbGxfY2ZnW2ldLmZi\n" - "ZGl2LCAwKSk7DQo+ICsJCQlwbGxfd3JpdGUoY2xrLCBQTExfUkVHX09ESVYsDQo+ICsJCQkJCWVu\n" - "Y29kZV9kaXYocGxsX2NmZ1tpXS5vZGl2LCAxKSk7DQo+ICsNCj4gKwkJCS8qDQo+ICsJCQnCoCog\n" - "V2FpdCB1bnRpbCBDR1UgcmVsb2Nrcy4NCj4gKwkJCcKgKiBJZiBhZnRlciB0aW1lb3V0IENHVSBp\n" - "cyB1bmxvY2tlZCB5ZXQgcmV0dXJuIGVycm9yDQo+ICsJCQnCoCovDQo+ICsJCQl1ZGVsYXkoUExM\n" - "X01BWF9MT0NLX1RJTUUpOw0KPiArCQkJaWYgKGlvcmVhZDMyKGNsay0+bG9jaykgJiBQTExfTE9D\n" - "SykNCj4gKwkJCQlyZXR1cm4gMDsNCj4gKwkJCWVsc2UNCj4gKwkJCQlyZXR1cm4gLUVUSU1FRE9V\n" - "VDsNCj4gKwkJfQ0KPiArCX0NCj4gKw0KPiArCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHJh\n" - "dGU9JWxkLCBwYXJlbnRfcmF0ZT0lbGRcbiIsIHJhdGUsDQo+ICsJCQlwYXJlbnRfcmF0ZSk7DQo+\n" - "ICsJcmV0dXJuIC1FSU5WQUw7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY2xr\n" - "X29wcyBwbGxfb3BzID0gew0KPiArCS5yZWNhbGNfcmF0ZSA9IHBsbF9yZWNhbGNfcmF0ZSwNCj4g\n" - "Kwkucm91bmRfcmF0ZSA9IHBsbF9yb3VuZF9yYXRlLA0KPiArCS5zZXRfcmF0ZSA9IHBsbF9zZXRf\n" - "cmF0ZSwNCj4gK307DQo+ICsNCj4gK3N0YXRpYyBpbnQgcGxsX2Nsa19wcm9iZShzdHJ1Y3QgcGxh\n" - "dGZvcm1fZGV2aWNlICpwZGV2KQ0KPiArew0KPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2\n" - "LT5kZXY7DQo+ICsJY29uc3QgY2hhciAqcGFyZW50X25hbWU7DQo+ICsJc3RydWN0IGNsayAqY2xr\n" - "Ow0KPiArCXN0cnVjdCBwbGxfY2xrICpwbGxfY2xrOw0KPiArCXN0cnVjdCByZXNvdXJjZSAqbWVt\n" - "Ow0KPiArCXN0cnVjdCBjbGtfaW5pdF9kYXRhIGluaXQgPSB7IH07DQo+ICsNCj4gKwlwbGxfY2xr\n" - "ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJ\n" - "aWYgKCFwbGxfY2xrKQ0KPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gKw0KPiArCW1lbSA9IHBsYXRm\n" - "b3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7DQo+ICsJcGxsX2Nsay0+\n" - "YmFzZSA9IGRldm1faW9yZW1hcF9yZXNvdXJjZShkZXYsIG1lbSk7DQo+ICsJaWYgKElTX0VSUihw\n" - "bGxfY2xrLT5iYXNlKSkNCj4gKwkJcmV0dXJuIFBUUl9FUlIocGxsX2Nsay0+YmFzZSk7DQo+ICsN\n" - "Cj4gKwltZW0gPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDEp\n" - "Ow0KPiArCXBsbF9jbGstPmxvY2sgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCBtZW0pOw0K\n" - "PiArCWlmIChJU19FUlIocGxsX2Nsay0+bG9jaykpDQo+ICsJCXJldHVybiBQVFJfRVJSKHBsbF9j\n" - "bGstPmJhc2UpOw0KPiArDQo+ICsJaW5pdC5uYW1lID0gZGV2LT5vZl9ub2RlLT5uYW1lOw0KPiAr\n" - "CWluaXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVu\n" - "dF9uYW1lKGRldi0+b2Zfbm9kZSwgMCk7DQo+ICsJaW5pdC5wYXJlbnRfbmFtZXMgPSAmcGFyZW50\n" - "X25hbWU7DQo+ICsJaW5pdC5udW1fcGFyZW50cyA9IDE7DQo+ICsJcGxsX2Nsay0+aHcuaW5pdCA9\n" - "ICZpbml0Ow0KPiArCXBsbF9jbGstPmRldiA9IGRldjsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9\n" - "IG9mX2RldmljZV9nZXRfbWF0Y2hfZGF0YShkZXYpOw0KPiArDQo+ICsJaWYgKCFwbGxfY2xrLT5w\n" - "bGxfZGF0YSkgew0KPiArCQlkZXZfZXJyKGRldiwgIk5vIE9GIG1hdGNoIGRhdGEgcHJvdmlkZWRc\n" - "biIpOw0KPiArCQkJcmV0dXJuIC1FSU5WQUw7DQo+ICsJfQ0KPiArDQo+ICsJY2xrID0gZGV2bV9j\n" - "bGtfcmVnaXN0ZXIoZGV2LCAmcGxsX2Nsay0+aHcpOw0KPiArCWlmIChJU19FUlIoY2xrKSkgew0K\n" - "PiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byByZWdpc3RlciAlcyBjbG9jayAoJWxkKVxuIiwN\n" - "Cj4gKwkJCQlpbml0Lm5hbWUsIFBUUl9FUlIoY2xrKSk7DQo+ICsJCXJldHVybiBQVFJfRVJSKGNs\n" - "ayk7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIG9mX2Nsa19hZGRfcHJvdmlkZXIoZGV2LT5vZl9u\n" - "b2RlLCBvZl9jbGtfc3JjX3NpbXBsZV9nZXQsIGNsayk7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBp\n" - "bnQgcGxsX2Nsa19yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gK3sNCj4g\n" - "KwlvZl9jbGtfZGVsX3Byb3ZpZGVyKHBkZXYtPmRldi5vZl9ub2RlKTsNCj4gKwlyZXR1cm4gMDsN\n" - "Cj4gK30NCj4gKw0KPiArc3RhdGljIHZvaWQgX19pbml0IG9mX3BsbF9jbGtfc2V0dXAoc3RydWN0\n" - "IGRldmljZV9ub2RlICpub2RlKQ0KPiArew0KPiArCWNvbnN0IGNoYXIgKnBhcmVudF9uYW1lOw0K\n" - "PiArCXN0cnVjdCBjbGsgKmNsazsNCj4gKwlzdHJ1Y3QgcGxsX2NsayAqcGxsX2NsazsNCj4gKwlz\n" - "dHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0ID0geyB9Ow0KPiArDQo+ICsJcGxsX2NsayA9IGt6YWxs\n" - "b2Moc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJaWYgKCFwbGxfY2xrKQ0KPiAr\n" - "CQlyZXR1cm47DQo+ICsNCj4gKwlwbGxfY2xrLT5iYXNlID0gb2ZfaW9tYXAobm9kZSwgMCk7DQo+\n" - "ICsJaWYgKCFwbGxfY2xrLT5iYXNlKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBwbGwg\n" - "ZGl2IHJlZ2lzdGVyc1xuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+YmFzZSk7DQo+ICsJCXJl\n" - "dHVybjsNCj4gKwl9DQo+ICsNCj4gKwlwbGxfY2xrLT5sb2NrID0gb2ZfaW9tYXAobm9kZSwgMSk7\n" - "DQo+ICsJaWYgKCFwbGxfY2xrLT5sb2NrKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBw\n" - "bGwgbG9jayByZWdpc3RlclxuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+bG9jayk7DQo+ICsJ\n" - "CXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlpbml0Lm5hbWUgPSBub2RlLT5uYW1lOw0KPiArCWlu\n" - "aXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVudF9u\n" - "YW1lKG5vZGUsIDApOw0KPiArCWluaXQucGFyZW50X25hbWVzID0gJnBhcmVudF9uYW1lOw0KPiAr\n" - "CWluaXQubnVtX3BhcmVudHMgPSBwYXJlbnRfbmFtZSA/IDEgOiAwOw0KPiArCXBsbF9jbGstPmh3\n" - "LmluaXQgPSAmaW5pdDsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9ICZhcmNfcGxsX2RhdGE7DQo+\n" - "ICsNCj4gKwljbGsgPSBjbGtfcmVnaXN0ZXIoTlVMTCwgJnBsbF9jbGstPmh3KTsNCj4gKwlpZiAo\n" - "SVNfRVJSKGNsaykpIHsNCj4gKwkJcHJfZXJyKCJmYWlsZWQgdG8gcmVnaXN0ZXIgJXMgY2xvY2sg\n" - "KCVsZClcbiIsDQo+ICsJCQkJbm9kZS0+bmFtZSwgUFRSX0VSUihjbGspKTsNCj4gKwkJa2ZyZWUo\n" - "cGxsX2Nsayk7DQo+ICsJCXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlvZl9jbGtfYWRkX3Byb3Zp\n" - "ZGVyKG5vZGUsIG9mX2Nsa19zcmNfc2ltcGxlX2dldCwgY2xrKTsNCj4gK30NCj4gKw0KPiArQ0xL\n" - "X09GX0RFQ0xBUkUoYXhzMTB4X3BsbF9jbG9jaywgInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2si\n" - "LCBvZl9wbGxfY2xrX3NldHVwKTsNCj4gKw0KPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp\n" - "Y2VfaWQgcGxsX2Nsa19pZFtdID0gew0KPiArCXsgLmNvbXBhdGlibGUgPSAic25wcyxheHMxMHgt\n" - "YXJjLXBsbC1jbG9jayIsIC5kYXRhID0gJmFyY19wbGxfZGF0YX0sDQo+ICsJeyAuY29tcGF0aWJs\n" - "ZSA9ICJzbnBzLGF4czEweC1wZ3UtcGxsLWNsb2NrIiwgLmRhdGEgPSAmcGd1X3BsbF9kYXRhfSwN\n" - "Cj4gKwl7IH0sDQo+ICt9Ow0KPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgcGxsX2Nsa19pZCk7\n" - "DQo+ICsNCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIHBsbF9jbGtfZHJpdmVyID0g\n" - "ew0KPiArCS5kcml2ZXIgPSB7DQo+ICsJCS5uYW1lID0gImF4czEweC1wbGwtY2xvY2siLA0KPiAr\n" - "CQkub2ZfbWF0Y2hfdGFibGUgPSBwbGxfY2xrX2lkLA0KPiArCX0sDQo+ICsJLnByb2JlID0gcGxs\n" - "X2Nsa19wcm9iZSwNCj4gKwkucmVtb3ZlID0gcGxsX2Nsa19yZW1vdmUsDQo+ICt9Ow0KPiArYnVp\n" - "bHRpbl9wbGF0Zm9ybV9kcml2ZXIocGxsX2Nsa19kcml2ZXIpOw0KPiArDQo+ICtNT0RVTEVfQVVU\n" - "SE9SKCJWbGFkIFpha2hhcm92IDx2emFraGFyQHN5bm9wc3lzLmNvbT4iKTsNCj4gK01PRFVMRV9E\n" - "RVNDUklQVElPTigiU3lub3BzeXMgQVhTMTBYIFNEUCBHZW5lcmljIFBMTCBDbG9jayBEcml2ZXIi\n" - "KTsNCj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsNCg0KTWF5YmUgeW91IGhhdmUgYW55IGNv\n" - "bW1lbnRzIG9yIHJlbWFya3MgYWJvdXQgdGhpcyBwYXRjaD8gQW5kIGlmIHlvdSBkb24ndCBjb3Vs\n" - "ZCB5b3UgcGxlYXNlIGFwcGx5IGl0Lg0KDQpUaGFua3MhDQoNCi0tIA0KQmVzdCByZWdhcmRzLA0K\n" - VmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+ + "Hi Michael, Stephen,\n" + "\n" + "On Tue, 2017-02-21@16:11 +0300, Vlad Zakharov wrote:\n" + "> AXS10X boards manages it's clocks using various PLLs. These PLL has same\n" + "> dividers and corresponding control registers mapped to different addresses.\n" + "> So we add one common driver for such PLLs.\n" + "> \n" + "> Each PLL on AXS10X board consist of three dividers: IDIV, FBDIV and\n" + "> ODIV. Output clock value is managed using these dividers.\n" + "> \n" + "> We add pre-defined tables with supported rate values and appropriate\n" + "> configurations of IDIV, FBDIV and ODIV for each value.\n" + "> \n" + "> As of today we add support for PLLs that generate clock for the\n" + "> following devices:\n" + "> ?* ARC core on AXC CPU tiles.\n" + "> ?* ARC PGU on ARC SDP Mainboard.\n" + "> and more to come later.\n" + "> \n" + "> Acked-by: Rob Herring <robh at kernel.org>\n" + "> Signed-off-by: Vlad Zakharov <vzakhar at synopsys.com>\n" + "> Signed-off-by: Jose Abreu <joabreu at synopsys.com>\n" + "> Cc: Michael Turquette <mturquette at baylibre.com>\n" + "> Cc: Stephen Boyd <sboyd at codeaurora.org>\n" + "> Cc: Mark Rutland <mark.rutland at arm.com>\n" + "> ---\n" + "> Cc: Rob Herring <robh at kernel.org>\n" + "> Changes v1..v2\n" + "> ?- Replace '_' with '-' in device tree nodes\n" + "> \n" + "> ?.../devicetree/bindings/clock/snps,pll-clock.txt???|??28 ++\n" + "> ?MAINTAINERS????????????????????????????????????????|???6 +\n" + "> ?drivers/clk/axs10x/Makefile????????????????????????|???1 +\n" + "> ?drivers/clk/axs10x/pll_clock.c?????????????????????| 384 +++++++++++++++++++++\n" + "> ?4 files changed, 419 insertions(+)\n" + "> ?create mode 100644 Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> ?create mode 100644 drivers/clk/axs10x/pll_clock.c\n" + "> \n" + "> diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> new file mode 100644\n" + "> index 0000000..5706246\n" + "> --- /dev/null\n" + "> +++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> @@ -0,0 +1,28 @@\n" + "> +Binding for the AXS10X Generic PLL clock\n" + "> +\n" + "> +This binding uses the common clock binding[1].\n" + "> +\n" + "> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt\n" + "> +\n" + "> +Required properties:\n" + "> +- compatible: should be \"snps,axs10x-<name>-pll-clock\"\n" + "> +??\"snps,axs10x-arc-pll-clock\"\n" + "> +??\"snps,axs10x-pgu-pll-clock\"\n" + "> +- reg: should always contain 2 pairs address - length: first for PLL config\n" + "> +registers and second for corresponding LOCK CGU register.\n" + "> +- clocks: shall be the input parent clock phandle for the PLL.\n" + "> +- #clock-cells: from common clock binding; Should always be set to 0.\n" + "> +\n" + "> +Example:\n" + "> +\tinput-clk: input-clk {\n" + "> +\t\tclock-frequency = <33333333>;\n" + "> +\t\tcompatible = \"fixed-clock\";\n" + "> +\t\t#clock-cells = <0>;\n" + "> +\t};\n" + "> +\n" + "> +\tcore-clk: core-clk at 80 {\n" + "> +\t\tcompatible = \"snps,axs10x-arc-pll-clock\";\n" + "> +\t\treg = <0x80 0x10 0x100 0x10>;\n" + "> +\t\t#clock-cells = <0>;\n" + "> +\t\tclocks = <&input-clk>;\n" + "> +\t};\n" + "> diff --git a/MAINTAINERS b/MAINTAINERS\n" + "> index 3960e7f..5805833 100644\n" + "> --- a/MAINTAINERS\n" + "> +++ b/MAINTAINERS\n" + "> @@ -11910,6 +11910,12 @@ F:\tarch/arc/plat-axs10x\n" + "> ?F:\tarch/arc/boot/dts/ax*\n" + "> ?F:\tDocumentation/devicetree/bindings/arc/axs10*\n" + "> ?\n" + "> +SYNOPSYS ARC SDP clock driver\n" + "> +M:\tVlad Zakharov <vzakhar at synopsys.com>\n" + "> +S:\tSupported\n" + "> +F:\tdrivers/clk/axs10x/*\n" + "> +F:\tDocumentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> +\n" + "> ?SYSTEM CONFIGURATION (SYSCON)\n" + "> ?M:\tLee Jones <lee.jones at linaro.org>\n" + "> ?M:\tArnd Bergmann <arnd at arndb.de>\n" + "> diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile\n" + "> index 01996b8..d747dea 100644\n" + "> --- a/drivers/clk/axs10x/Makefile\n" + "> +++ b/drivers/clk/axs10x/Makefile\n" + "> @@ -1 +1,2 @@\n" + "> ?obj-y += i2s_pll_clock.o\n" + "> +obj-y += pll_clock.o\n" + "> diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c\n" + "> new file mode 100644\n" + "> index 0000000..784a0a2\n" + "> --- /dev/null\n" + "> +++ b/drivers/clk/axs10x/pll_clock.c\n" + "> @@ -0,0 +1,384 @@\n" + "> +/*\n" + "> + * Synopsys AXS10X SDP Generic PLL clock driver\n" + "> + *\n" + "> + * Copyright (C) 2017 Synopsys\n" + "> + *\n" + "> + * This file is licensed under the terms of the GNU General Public\n" + "> + * License version 2. This program is licensed \"as is\" without any\n" + "> + * warranty of any kind, whether express or implied.\n" + "> + */\n" + "> +\n" + "> +#include <linux/platform_device.h>\n" + "> +#include <linux/module.h>\n" + "> +#include <linux/clk-provider.h>\n" + "> +#include <linux/delay.h>\n" + "> +#include <linux/err.h>\n" + "> +#include <linux/device.h>\n" + "> +#include <linux/of_address.h>\n" + "> +#include <linux/of_device.h>\n" + "> +#include <linux/slab.h>\n" + "> +#include <linux/of.h>\n" + "> +\n" + "> +/* PLL registers addresses */\n" + "> +#define PLL_REG_IDIV\t0x0\n" + "> +#define PLL_REG_FBDIV\t0x4\n" + "> +#define PLL_REG_ODIV\t0x8\n" + "> +\n" + "> +/*\n" + "> + * Bit fields of the PLL IDIV/FBDIV/ODIV registers:\n" + "> + *??________________________________________________________________________\n" + "> + * |31????????????????15|????14????|???13???|??12??|11?????????6|5?????????0|\n" + "> + * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--|\n" + "> + * |____________________|__________|________|______|____________|___________|\n" + "> + *\n" + "> + * Following macros detirmine the way of access to these registers\n" + "> + * They should be set up only using the macros.\n" + "> + * reg should be and uint32_t variable.\n" + "> + */\n" + "> +\n" + "> +#define PLL_REG_GET_LOW(reg)\t\t\t\\\n" + "> +\t(((reg) & (0x3F << 0)) >> 0)\n" + "> +#define PLL_REG_GET_HIGH(reg)\t\t\t\\\n" + "> +\t(((reg) & (0x3F << 6)) >> 6)\n" + "> +#define PLL_REG_GET_EDGE(reg)\t\t\t\\\n" + "> +\t(((reg) & (BIT(12))) ? 1 : 0)\n" + "> +#define PLL_REG_GET_BYPASS(reg)\t\t\t\\\n" + "> +\t(((reg) & (BIT(13))) ? 1 : 0)\n" + "> +#define PLL_REG_GET_NOUPD(reg)\t\t\t\\\n" + "> +\t(((reg) & (BIT(14))) ? 1 : 0)\n" + "> +#define PLL_REG_GET_PAD(reg)\t\t\t\\\n" + "> +\t(((reg) & (0x1FFFF << 15)) >> 15)\n" + "> +\n" + "> +#define PLL_REG_SET_LOW(reg, value)\t\t\\\n" + "> +\t{ reg |= (((value) & 0x3F) << 0); }\n" + "> +#define PLL_REG_SET_HIGH(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x3F) << 6); }\n" + "> +#define PLL_REG_SET_EDGE(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x01) << 12); }\n" + "> +#define PLL_REG_SET_BYPASS(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x01) << 13); }\n" + "> +#define PLL_REG_SET_NOUPD(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x01) << 14); }\n" + "> +#define PLL_REG_SET_PAD(reg, value)\t\t\\\n" + "> +\t{ reg |= (((value) & 0x1FFFF) << 15); }\n" + "> +\n" + "> +#define PLL_LOCK\t0x1\n" + "> +#define PLL_MAX_LOCK_TIME 100 /* 100 us */\n" + "> +\n" + "> +struct pll_cfg {\n" + "> +\tu32 rate;\n" + "> +\tu32 idiv;\n" + "> +\tu32 fbdiv;\n" + "> +\tu32 odiv;\n" + "> +};\n" + "> +\n" + "> +struct pll_of_table {\n" + "> +\tunsigned long prate;\n" + "> +\tstruct pll_cfg *pll_cfg_table;\n" + "> +};\n" + "> +\n" + "> +struct pll_of_data {\n" + "> +\tstruct pll_of_table *pll_table;\n" + "> +};\n" + "> +\n" + "> +static struct pll_of_data pgu_pll_data = {\n" + "> +\t.pll_table = (struct pll_of_table []){\n" + "> +\t\t{\n" + "> +\t\t\t.prate = 27000000,\n" + "> +\t\t\t.pll_cfg_table = (struct pll_cfg []){\n" + "> +\t\t\t\t{ 25200000, 1, 84, 90 },\n" + "> +\t\t\t\t{ 50000000, 1, 100, 54 },\n" + "> +\t\t\t\t{ 74250000, 1, 44, 16 },\n" + "> +\t\t\t\t{ },\n" + "> +\t\t\t},\n" + "> +\t\t},\n" + "> +\t\t/* Used as list limiter */\n" + "> +\t\t{ },\n" + "> +\t},\n" + "> +};\n" + "> +\n" + "> +static struct pll_of_data arc_pll_data = {\n" + "> +\t.pll_table = (struct pll_of_table []){\n" + "> +\t\t{\n" + "> +\t\t\t.prate = 33333333,\n" + "> +\t\t\t.pll_cfg_table = (struct pll_cfg []){\n" + "> +\t\t\t\t{ 33333333,??1, 1,??1 },\n" + "> +\t\t\t\t{ 50000000,??1, 30, 20 },\n" + "> +\t\t\t\t{ 75000000,??2, 45, 10 },\n" + "> +\t\t\t\t{ 90000000,??2, 54, 10 },\n" + "> +\t\t\t\t{ 100000000, 1, 30, 10 },\n" + "> +\t\t\t\t{ 125000000, 2, 45, 6 },\n" + "> +\t\t\t\t{ },\n" + "> +\t\t\t},\n" + "> +\t\t},\n" + "> +\t\t/* Used as list limiter */\n" + "> +\t\t{ },\n" + "> +\t},\n" + "> +};\n" + "> +\n" + "> +struct pll_clk {\n" + "> +\tvoid __iomem *base;\n" + "> +\tvoid __iomem *lock;\n" + "> +\tconst struct pll_of_data *pll_data;\n" + "> +\tstruct clk_hw hw;\n" + "> +\tstruct device *dev;\n" + "> +};\n" + "> +\n" + "> +static inline void pll_write(struct pll_clk *clk, unsigned int reg,\n" + "> +\t\tunsigned int val)\n" + "> +{\n" + "> +\tiowrite32(val, clk->base + reg);\n" + "> +}\n" + "> +\n" + "> +static inline u32 pll_read(struct pll_clk *clk,\n" + "> +\t\tunsigned int reg)\n" + "> +{\n" + "> +\treturn ioread32(clk->base + reg);\n" + "> +}\n" + "> +\n" + "> +static inline struct pll_clk *to_pll_clk(struct clk_hw *hw)\n" + "> +{\n" + "> +\treturn container_of(hw, struct pll_clk, hw);\n" + "> +}\n" + "> +\n" + "> +static inline u32 div_get_value(unsigned int reg)\n" + "> +{\n" + "> +\tif (PLL_REG_GET_BYPASS(reg))\n" + "> +\t\treturn 1;\n" + "> +\n" + "> +\treturn (PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg));\n" + "> +}\n" + "> +\n" + "> +static inline u32 encode_div(unsigned int id, int upd)\n" + "> +{\n" + "> +\tuint32_t div = 0;\n" + "> +\n" + "> +\tPLL_REG_SET_LOW(div, (id%2 == 0) ? id >> 1 : (id >> 1) + 1);\n" + "> +\tPLL_REG_SET_HIGH(div, id >> 1);\n" + "> +\tPLL_REG_SET_EDGE(div, id%2);\n" + "> +\tPLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0);\n" + "> +\tPLL_REG_SET_NOUPD(div, !upd);\n" + "> +\n" + "> +\treturn div;\n" + "> +}\n" + "> +\n" + "> +static const struct pll_cfg *pll_get_cfg(unsigned long prate,\n" + "> +\t\tconst struct pll_of_table *pll_table)\n" + "> +{\n" + "> +\tint i;\n" + "> +\n" + "> +\tfor (i = 0; pll_table[i].prate != 0; i++)\n" + "> +\t\tif (pll_table[i].prate == prate)\n" + "> +\t\t\treturn pll_table[i].pll_cfg_table;\n" + "> +\n" + "> +\treturn NULL;\n" + "> +}\n" + "> +\n" + "> +static unsigned long pll_recalc_rate(struct clk_hw *hw,\n" + "> +\t\t\tunsigned long parent_rate)\n" + "> +{\n" + "> +\tu64 rate;\n" + "> +\tu32 idiv, fbdiv, odiv;\n" + "> +\tstruct pll_clk *clk = to_pll_clk(hw);\n" + "> +\n" + "> +\tidiv = div_get_value(pll_read(clk, PLL_REG_IDIV));\n" + "> +\tfbdiv = div_get_value(pll_read(clk, PLL_REG_FBDIV));\n" + "> +\todiv = div_get_value(pll_read(clk, PLL_REG_ODIV));\n" + "> +\n" + "> +\trate = (u64)parent_rate * fbdiv;\n" + "> +\tdo_div(rate, idiv * odiv);\n" + "> +\n" + "> +\treturn (unsigned long)rate;\n" + "> +}\n" + "> +\n" + "> +static long pll_round_rate(struct clk_hw *hw, unsigned long rate,\n" + "> +\t\t\tunsigned long *prate)\n" + "> +{\n" + "> +\tint i;\n" + "> +\tlong best_rate;\n" + "> +\tstruct pll_clk *clk = to_pll_clk(hw);\n" + "> +\tconst struct pll_cfg *pll_cfg = pll_get_cfg(*prate,\n" + "> +\t\t\tclk->pll_data->pll_table);\n" + "> +\n" + "> +\tif (!pll_cfg) {\n" + "> +\t\tdev_err(clk->dev, \"invalid parent rate=%ld\\n\", *prate);\n" + "> +\t\treturn -EINVAL;\n" + "> +\t}\n" + "> +\n" + "> +\tif (pll_cfg[0].rate == 0)\n" + "> +\t\treturn -EINVAL;\n" + "> +\n" + "> +\tbest_rate = pll_cfg[0].rate;\n" + "> +\n" + "> +\tfor (i = 1; pll_cfg[i].rate != 0; i++) {\n" + "> +\t\tif (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate))\n" + "> +\t\t\tbest_rate = pll_cfg[i].rate;\n" + "> +\t}\n" + "> +\n" + "> +\treturn best_rate;\n" + "> +}\n" + "> +\n" + "> +static int pll_set_rate(struct clk_hw *hw, unsigned long rate,\n" + "> +\t\t\tunsigned long parent_rate)\n" + "> +{\n" + "> +\tint i;\n" + "> +\tstruct pll_clk *clk = to_pll_clk(hw);\n" + "> +\tconst struct pll_cfg *pll_cfg = pll_get_cfg(parent_rate,\n" + "> +\t\t\tclk->pll_data->pll_table);\n" + "> +\n" + "> +\tif (!pll_cfg) {\n" + "> +\t\tdev_err(clk->dev, \"invalid parent rate=%ld\\n\", parent_rate);\n" + "> +\t\treturn -EINVAL;\n" + "> +\t}\n" + "> +\n" + "> +\tfor (i = 0; pll_cfg[i].rate != 0; i++) {\n" + "> +\t\tif (pll_cfg[i].rate == rate) {\n" + "> +\t\t\tpll_write(clk, PLL_REG_IDIV,\n" + "> +\t\t\t\t\tencode_div(pll_cfg[i].idiv, 0));\n" + "> +\t\t\tpll_write(clk, PLL_REG_FBDIV,\n" + "> +\t\t\t\t\tencode_div(pll_cfg[i].fbdiv, 0));\n" + "> +\t\t\tpll_write(clk, PLL_REG_ODIV,\n" + "> +\t\t\t\t\tencode_div(pll_cfg[i].odiv, 1));\n" + "> +\n" + "> +\t\t\t/*\n" + "> +\t\t\t?* Wait until CGU relocks.\n" + "> +\t\t\t?* If after timeout CGU is unlocked yet return error\n" + "> +\t\t\t?*/\n" + "> +\t\t\tudelay(PLL_MAX_LOCK_TIME);\n" + "> +\t\t\tif (ioread32(clk->lock) & PLL_LOCK)\n" + "> +\t\t\t\treturn 0;\n" + "> +\t\t\telse\n" + "> +\t\t\t\treturn -ETIMEDOUT;\n" + "> +\t\t}\n" + "> +\t}\n" + "> +\n" + "> +\tdev_err(clk->dev, \"invalid rate=%ld, parent_rate=%ld\\n\", rate,\n" + "> +\t\t\tparent_rate);\n" + "> +\treturn -EINVAL;\n" + "> +}\n" + "> +\n" + "> +static const struct clk_ops pll_ops = {\n" + "> +\t.recalc_rate = pll_recalc_rate,\n" + "> +\t.round_rate = pll_round_rate,\n" + "> +\t.set_rate = pll_set_rate,\n" + "> +};\n" + "> +\n" + "> +static int pll_clk_probe(struct platform_device *pdev)\n" + "> +{\n" + "> +\tstruct device *dev = &pdev->dev;\n" + "> +\tconst char *parent_name;\n" + "> +\tstruct clk *clk;\n" + "> +\tstruct pll_clk *pll_clk;\n" + "> +\tstruct resource *mem;\n" + "> +\tstruct clk_init_data init = { };\n" + "> +\n" + "> +\tpll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);\n" + "> +\tif (!pll_clk)\n" + "> +\t\treturn -ENOMEM;\n" + "> +\n" + "> +\tmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n" + "> +\tpll_clk->base = devm_ioremap_resource(dev, mem);\n" + "> +\tif (IS_ERR(pll_clk->base))\n" + "> +\t\treturn PTR_ERR(pll_clk->base);\n" + "> +\n" + "> +\tmem = platform_get_resource(pdev, IORESOURCE_MEM, 1);\n" + "> +\tpll_clk->lock = devm_ioremap_resource(dev, mem);\n" + "> +\tif (IS_ERR(pll_clk->lock))\n" + "> +\t\treturn PTR_ERR(pll_clk->base);\n" + "> +\n" + "> +\tinit.name = dev->of_node->name;\n" + "> +\tinit.ops = &pll_ops;\n" + "> +\tparent_name = of_clk_get_parent_name(dev->of_node, 0);\n" + "> +\tinit.parent_names = &parent_name;\n" + "> +\tinit.num_parents = 1;\n" + "> +\tpll_clk->hw.init = &init;\n" + "> +\tpll_clk->dev = dev;\n" + "> +\tpll_clk->pll_data = of_device_get_match_data(dev);\n" + "> +\n" + "> +\tif (!pll_clk->pll_data) {\n" + "> +\t\tdev_err(dev, \"No OF match data provided\\n\");\n" + "> +\t\t\treturn -EINVAL;\n" + "> +\t}\n" + "> +\n" + "> +\tclk = devm_clk_register(dev, &pll_clk->hw);\n" + "> +\tif (IS_ERR(clk)) {\n" + "> +\t\tdev_err(dev, \"failed to register %s clock (%ld)\\n\",\n" + "> +\t\t\t\tinit.name, PTR_ERR(clk));\n" + "> +\t\treturn PTR_ERR(clk);\n" + "> +\t}\n" + "> +\n" + "> +\treturn of_clk_add_provider(dev->of_node, of_clk_src_simple_get, clk);\n" + "> +}\n" + "> +\n" + "> +static int pll_clk_remove(struct platform_device *pdev)\n" + "> +{\n" + "> +\tof_clk_del_provider(pdev->dev.of_node);\n" + "> +\treturn 0;\n" + "> +}\n" + "> +\n" + "> +static void __init of_pll_clk_setup(struct device_node *node)\n" + "> +{\n" + "> +\tconst char *parent_name;\n" + "> +\tstruct clk *clk;\n" + "> +\tstruct pll_clk *pll_clk;\n" + "> +\tstruct clk_init_data init = { };\n" + "> +\n" + "> +\tpll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);\n" + "> +\tif (!pll_clk)\n" + "> +\t\treturn;\n" + "> +\n" + "> +\tpll_clk->base = of_iomap(node, 0);\n" + "> +\tif (!pll_clk->base) {\n" + "> +\t\tpr_err(\"failed to map pll div registers\\n\");\n" + "> +\t\tiounmap(pll_clk->base);\n" + "> +\t\treturn;\n" + "> +\t}\n" + "> +\n" + "> +\tpll_clk->lock = of_iomap(node, 1);\n" + "> +\tif (!pll_clk->lock) {\n" + "> +\t\tpr_err(\"failed to map pll lock register\\n\");\n" + "> +\t\tiounmap(pll_clk->lock);\n" + "> +\t\treturn;\n" + "> +\t}\n" + "> +\n" + "> +\tinit.name = node->name;\n" + "> +\tinit.ops = &pll_ops;\n" + "> +\tparent_name = of_clk_get_parent_name(node, 0);\n" + "> +\tinit.parent_names = &parent_name;\n" + "> +\tinit.num_parents = parent_name ? 1 : 0;\n" + "> +\tpll_clk->hw.init = &init;\n" + "> +\tpll_clk->pll_data = &arc_pll_data;\n" + "> +\n" + "> +\tclk = clk_register(NULL, &pll_clk->hw);\n" + "> +\tif (IS_ERR(clk)) {\n" + "> +\t\tpr_err(\"failed to register %s clock (%ld)\\n\",\n" + "> +\t\t\t\tnode->name, PTR_ERR(clk));\n" + "> +\t\tkfree(pll_clk);\n" + "> +\t\treturn;\n" + "> +\t}\n" + "> +\n" + "> +\tof_clk_add_provider(node, of_clk_src_simple_get, clk);\n" + "> +}\n" + "> +\n" + "> +CLK_OF_DECLARE(axs10x_pll_clock, \"snps,axs10x-arc-pll-clock\", of_pll_clk_setup);\n" + "> +\n" + "> +static const struct of_device_id pll_clk_id[] = {\n" + "> +\t{ .compatible = \"snps,axs10x-arc-pll-clock\", .data = &arc_pll_data},\n" + "> +\t{ .compatible = \"snps,axs10x-pgu-pll-clock\", .data = &pgu_pll_data},\n" + "> +\t{ },\n" + "> +};\n" + "> +MODULE_DEVICE_TABLE(of, pll_clk_id);\n" + "> +\n" + "> +static struct platform_driver pll_clk_driver = {\n" + "> +\t.driver = {\n" + "> +\t\t.name = \"axs10x-pll-clock\",\n" + "> +\t\t.of_match_table = pll_clk_id,\n" + "> +\t},\n" + "> +\t.probe = pll_clk_probe,\n" + "> +\t.remove = pll_clk_remove,\n" + "> +};\n" + "> +builtin_platform_driver(pll_clk_driver);\n" + "> +\n" + "> +MODULE_AUTHOR(\"Vlad Zakharov <vzakhar at synopsys.com>\");\n" + "> +MODULE_DESCRIPTION(\"Synopsys AXS10X SDP Generic PLL Clock Driver\");\n" + "> +MODULE_LICENSE(\"GPL v2\");\n" + "\n" + "Maybe you have any comments or remarks about this patch? And if you don't could you please apply it.\n" + "\n" + "Thanks!\n" + "\n" + "-- \n" + "Best regards,\n" + Vlad Zakharov <vzakhar at synopsys.com> -36fae7fa84d07b8086c925e623f6ba88940d662237db2b05d1e273fbce8d0b15 +f7738f0be57707eaf24bfd8db48270aab42bc45a79e0f67507415aacfc4a0ba0
diff --git a/a/1.txt b/N2/1.txt index 1a5bc4f..85817e4 100644 --- a/a/1.txt +++ b/N2/1.txt @@ -1,265 +1,495 @@ -SGkgTWljaGFlbCwgU3RlcGhlbiwNCg0KT24gVHVlLCAyMDE3LTAyLTIxIGF0IDE2OjExICswMzAw -LCBWbGFkIFpha2hhcm92IHdyb3RlOg0KPiBBWFMxMFggYm9hcmRzIG1hbmFnZXMgaXQncyBjbG9j -a3MgdXNpbmcgdmFyaW91cyBQTExzLiBUaGVzZSBQTEwgaGFzIHNhbWUNCj4gZGl2aWRlcnMgYW5k -IGNvcnJlc3BvbmRpbmcgY29udHJvbCByZWdpc3RlcnMgbWFwcGVkIHRvIGRpZmZlcmVudCBhZGRy -ZXNzZXMuDQo+IFNvIHdlIGFkZCBvbmUgY29tbW9uIGRyaXZlciBmb3Igc3VjaCBQTExzLg0KPiAN -Cj4gRWFjaCBQTEwgb24gQVhTMTBYIGJvYXJkIGNvbnNpc3Qgb2YgdGhyZWUgZGl2aWRlcnM6IElE -SVYsIEZCRElWIGFuZA0KPiBPRElWLiBPdXRwdXQgY2xvY2sgdmFsdWUgaXMgbWFuYWdlZCB1c2lu -ZyB0aGVzZSBkaXZpZGVycy4NCj4gDQo+IFdlIGFkZCBwcmUtZGVmaW5lZCB0YWJsZXMgd2l0aCBz -dXBwb3J0ZWQgcmF0ZSB2YWx1ZXMgYW5kIGFwcHJvcHJpYXRlDQo+IGNvbmZpZ3VyYXRpb25zIG9m -IElESVYsIEZCRElWIGFuZCBPRElWIGZvciBlYWNoIHZhbHVlLg0KPiANCj4gQXMgb2YgdG9kYXkg -d2UgYWRkIHN1cHBvcnQgZm9yIFBMTHMgdGhhdCBnZW5lcmF0ZSBjbG9jayBmb3IgdGhlDQo+IGZv -bGxvd2luZyBkZXZpY2VzOg0KPiDCoCogQVJDIGNvcmUgb24gQVhDIENQVSB0aWxlcy4NCj4gwqAq -IEFSQyBQR1Ugb24gQVJDIFNEUCBNYWluYm9hcmQuDQo+IGFuZCBtb3JlIHRvIGNvbWUgbGF0ZXIu -DQo+IA0KPiBBY2tlZC1ieTogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gU2lnbmVk -LW9mZi1ieTogVmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+DQo+IFNpZ25lZC1v -ZmYtYnk6IEpvc2UgQWJyZXUgPGpvYWJyZXVAc3lub3BzeXMuY29tPg0KPiBDYzogTWljaGFlbCBU -dXJxdWV0dGUgPG10dXJxdWV0dGVAYmF5bGlicmUuY29tPg0KPiBDYzogU3RlcGhlbiBCb3lkIDxz -Ym95ZEBjb2RlYXVyb3JhLm9yZz4NCj4gQ2M6IE1hcmsgUnV0bGFuZCA8bWFyay5ydXRsYW5kQGFy -bS5jb20+DQo+IC0tLQ0KPiBDYzogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gQ2hh -bmdlcyB2MS4udjINCj4gwqAtIFJlcGxhY2UgJ18nIHdpdGggJy0nIGluIGRldmljZSB0cmVlIG5v -ZGVzDQo+IA0KPiDCoC4uLi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxsLWNsb2Nr -LnR4dMKgwqDCoHzCoMKgMjggKysNCj4gwqBNQUlOVEFJTkVSU8KgwqDCoMKgwqDCoMKgwqDCoMKg -wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC -oMKgfMKgwqDCoDYgKw0KPiDCoGRyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZcKgwqDCoMKgwqDC -oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAxICsNCj4gwqBkcml2 -ZXJzL2Nsay9heHMxMHgvcGxsX2Nsb2NrLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC -oMKgwqDCoMKgwqB8IDM4NCArKysrKysrKysrKysrKysrKysrKysNCj4gwqA0IGZpbGVzIGNoYW5n -ZWQsIDQxOSBpbnNlcnRpb25zKCspDQo+IMKgY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp -b24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gwqBjcmVh -dGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IA0KPiBkaWZm -IC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxs -LWNsb2NrLnR4dA0KPiBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9z -bnBzLHBsbC1jbG9jay50eHQNCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gaW5kZXggMDAwMDAw -MC4uNTcwNjI0Ng0KPiAtLS0gL2Rldi9udWxsDQo+ICsrKyBiL0RvY3VtZW50YXRpb24vZGV2aWNl -dHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gQEAgLTAsMCArMSwyOCBA -QA0KPiArQmluZGluZyBmb3IgdGhlIEFYUzEwWCBHZW5lcmljIFBMTCBjbG9jaw0KPiArDQo+ICtU -aGlzIGJpbmRpbmcgdXNlcyB0aGUgY29tbW9uIGNsb2NrIGJpbmRpbmdbMV0uDQo+ICsNCj4gK1sx -XSBEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvY2xvY2svY2xvY2stYmluZGluZ3Mu -dHh0DQo+ICsNCj4gK1JlcXVpcmVkIHByb3BlcnRpZXM6DQo+ICstIGNvbXBhdGlibGU6IHNob3Vs -ZCBiZSAic25wcyxheHMxMHgtPG5hbWU+LXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgt -YXJjLXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgtcGd1LXBsbC1jbG9jayINCj4gKy0g -cmVnOiBzaG91bGQgYWx3YXlzIGNvbnRhaW4gMiBwYWlycyBhZGRyZXNzIC0gbGVuZ3RoOiBmaXJz -dCBmb3IgUExMIGNvbmZpZw0KPiArcmVnaXN0ZXJzIGFuZCBzZWNvbmQgZm9yIGNvcnJlc3BvbmRp -bmcgTE9DSyBDR1UgcmVnaXN0ZXIuDQo+ICstIGNsb2Nrczogc2hhbGwgYmUgdGhlIGlucHV0IHBh -cmVudCBjbG9jayBwaGFuZGxlIGZvciB0aGUgUExMLg0KPiArLSAjY2xvY2stY2VsbHM6IGZyb20g -Y29tbW9uIGNsb2NrIGJpbmRpbmc7IFNob3VsZCBhbHdheXMgYmUgc2V0IHRvIDAuDQo+ICsNCj4g -K0V4YW1wbGU6DQo+ICsJaW5wdXQtY2xrOiBpbnB1dC1jbGsgew0KPiArCQljbG9jay1mcmVxdWVu -Y3kgPSA8MzMzMzMzMzM+Ow0KPiArCQljb21wYXRpYmxlID0gImZpeGVkLWNsb2NrIjsNCj4gKwkJ -I2Nsb2NrLWNlbGxzID0gPDA+Ow0KPiArCX07DQo+ICsNCj4gKwljb3JlLWNsazogY29yZS1jbGtA -ODAgew0KPiArCQljb21wYXRpYmxlID0gInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2siOw0KPiAr -CQlyZWcgPSA8MHg4MCAweDEwIDB4MTAwIDB4MTA+Ow0KPiArCQkjY2xvY2stY2VsbHMgPSA8MD47 -DQo+ICsJCWNsb2NrcyA9IDwmaW5wdXQtY2xrPjsNCj4gKwl9Ow0KPiBkaWZmIC0tZ2l0IGEvTUFJ -TlRBSU5FUlMgYi9NQUlOVEFJTkVSUw0KPiBpbmRleCAzOTYwZTdmLi41ODA1ODMzIDEwMDY0NA0K -PiAtLS0gYS9NQUlOVEFJTkVSUw0KPiArKysgYi9NQUlOVEFJTkVSUw0KPiBAQCAtMTE5MTAsNiAr -MTE5MTAsMTIgQEAgRjoJYXJjaC9hcmMvcGxhdC1heHMxMHgNCj4gwqBGOglhcmNoL2FyYy9ib290 -L2R0cy9heCoNCj4gwqBGOglEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvYXJjL2F4 -czEwKg0KPiDCoA0KPiArU1lOT1BTWVMgQVJDIFNEUCBjbG9jayBkcml2ZXINCj4gK006CVZsYWQg -WmFraGFyb3YgPHZ6YWtoYXJAc3lub3BzeXMuY29tPg0KPiArUzoJU3VwcG9ydGVkDQo+ICtGOglk -cml2ZXJzL2Nsay9heHMxMHgvKg0KPiArRjoJRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRp -bmdzL2Nsb2NrL3NucHMscGxsLWNsb2NrLnR4dA0KPiArDQo+IMKgU1lTVEVNIENPTkZJR1VSQVRJ -T04gKFNZU0NPTikNCj4gwqBNOglMZWUgSm9uZXMgPGxlZS5qb25lc0BsaW5hcm8ub3JnPg0KPiDC -oE06CUFybmQgQmVyZ21hbm4gPGFybmRAYXJuZGIuZGU+DQo+IGRpZmYgLS1naXQgYS9kcml2ZXJz -L2Nsay9heHMxMHgvTWFrZWZpbGUgYi9kcml2ZXJzL2Nsay9heHMxMHgvTWFrZWZpbGUNCj4gaW5k -ZXggMDE5OTZiOC4uZDc0N2RlYSAxMDA2NDQNCj4gLS0tIGEvZHJpdmVycy9jbGsvYXhzMTB4L01h -a2VmaWxlDQo+ICsrKyBiL2RyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZQ0KPiBAQCAtMSArMSwy -IEBADQo+IMKgb2JqLXkgKz0gaTJzX3BsbF9jbG9jay5vDQo+ICtvYmoteSArPSBwbGxfY2xvY2su -bw0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jIGIvZHJpdmVy -cy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+IGluZGV4 -IDAwMDAwMDAuLjc4NGEwYTINCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJzL2Nsay9h -eHMxMHgvcGxsX2Nsb2NrLmMNCj4gQEAgLTAsMCArMSwzODQgQEANCj4gKy8qDQo+ICsgKiBTeW5v -cHN5cyBBWFMxMFggU0RQIEdlbmVyaWMgUExMIGNsb2NrIGRyaXZlcg0KPiArICoNCj4gKyAqIENv -cHlyaWdodCAoQykgMjAxNyBTeW5vcHN5cw0KPiArICoNCj4gKyAqIFRoaXMgZmlsZSBpcyBsaWNl -bnNlZCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYw0KPiArICogTGlj -ZW5zZSB2ZXJzaW9uIDIuIFRoaXMgcHJvZ3JhbSBpcyBsaWNlbnNlZCAiYXMgaXMiIHdpdGhvdXQg -YW55DQo+ICsgKiB3YXJyYW50eSBvZiBhbnkga2luZCwgd2hldGhlciBleHByZXNzIG9yIGltcGxp -ZWQuDQo+ICsgKi8NCj4gKw0KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPg0K -PiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92 -aWRlci5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+DQo+ICsjaW5jbHVkZSA8bGludXgv -ZXJyLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ICsjaW5jbHVkZSA8bGludXgv -b2ZfYWRkcmVzcy5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPg0KPiArI2luY2x1 -ZGUgPGxpbnV4L3NsYWIuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPg0KPiArDQo+ICsvKiBQ -TEwgcmVnaXN0ZXJzIGFkZHJlc3NlcyAqLw0KPiArI2RlZmluZSBQTExfUkVHX0lESVYJMHgwDQo+ -ICsjZGVmaW5lIFBMTF9SRUdfRkJESVYJMHg0DQo+ICsjZGVmaW5lIFBMTF9SRUdfT0RJVgkweDgN -Cj4gKw0KPiArLyoNCj4gKyAqIEJpdCBmaWVsZHMgb2YgdGhlIFBMTCBJRElWL0ZCRElWL09ESVYg -cmVnaXN0ZXJzOg0KPiArICrCoMKgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f -X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQo+ICsgKiB8MzHCoMKgwqDCoMKg -wqDCoMKgwqDCoMKgwqDCoMKgwqDCoDE1fMKgwqDCoMKgMTTCoMKgwqDCoHzCoMKgwqAxM8KgwqDC -oHzCoMKgMTLCoMKgfDExwqDCoMKgwqDCoMKgwqDCoMKgNnw1wqDCoMKgwqDCoMKgwqDCoMKgMHwN -Cj4gKyAqIHwtLS0tLS0tUkVTUlZFRC0tLS0tLXwtTk9VUERBVEUtfC1CWVBBU1MtfC1FREdFLXwt -LUhJR0hUSU1FLS18LS1MT1dUSU1FLS18DQo+ICsgKiB8X19fX19fX19fX19fX19fX19fX198X19f -X19fX19fX3xfX19fX19fX3xfX19fX198X19fX19fX19fX19ffF9fX19fX19fX19ffA0KPiArICoN -Cj4gKyAqIEZvbGxvd2luZyBtYWNyb3MgZGV0aXJtaW5lIHRoZSB3YXkgb2YgYWNjZXNzIHRvIHRo -ZXNlIHJlZ2lzdGVycw0KPiArICogVGhleSBzaG91bGQgYmUgc2V0IHVwIG9ubHkgdXNpbmcgdGhl -IG1hY3Jvcy4NCj4gKyAqIHJlZyBzaG91bGQgYmUgYW5kIHVpbnQzMl90IHZhcmlhYmxlLg0KPiAr -ICovDQo+ICsNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTE9XKHJlZykJCQlcDQo+ICsJKCgocmVn -KSAmICgweDNGIDw8IDApKSA+PiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9ISUdIKHJlZykJ -CQlcDQo+ICsJKCgocmVnKSAmICgweDNGIDw8IDYpKSA+PiA2KQ0KPiArI2RlZmluZSBQTExfUkVH -X0dFVF9FREdFKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQoMTIpKSkgPyAxIDogMCkNCj4g -KyNkZWZpbmUgUExMX1JFR19HRVRfQllQQVNTKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQo -MTMpKSkgPyAxIDogMCkNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTk9VUEQocmVnKQkJCVwNCj4g -KwkoKChyZWcpICYgKEJJVCgxNCkpKSA/IDEgOiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9Q -QUQocmVnKQkJCVwNCj4gKwkoKChyZWcpICYgKDB4MUZGRkYgPDwgMTUpKSA+PiAxNSkNCj4gKw0K -PiArI2RlZmluZSBQTExfUkVHX1NFVF9MT1cocmVnLCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAo -KCh2YWx1ZSkgJiAweDNGKSA8PCAwKTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9ISUdIKHJl -ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDNGKSA8PCA2KTsgfQ0KPiAr -I2RlZmluZSBQTExfUkVHX1NFVF9FREdFKHJlZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2 -YWx1ZSkgJiAweDAxKSA8PCAxMik7IH0NCj4gKyNkZWZpbmUgUExMX1JFR19TRVRfQllQQVNTKHJl -ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDAxKSA8PCAxMyk7IH0NCj4g -KyNkZWZpbmUgUExMX1JFR19TRVRfTk9VUEQocmVnLCB2YWx1ZSkJXA0KPiArCXsgcmVnIHw9ICgo -KHZhbHVlKSAmIDB4MDEpIDw8IDE0KTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9QQUQocmVn -LCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDFGRkZGKSA8PCAxNSk7IH0N -Cj4gKw0KPiArI2RlZmluZSBQTExfTE9DSwkweDENCj4gKyNkZWZpbmUgUExMX01BWF9MT0NLX1RJ -TUUgMTAwIC8qIDEwMCB1cyAqLw0KPiArDQo+ICtzdHJ1Y3QgcGxsX2NmZyB7DQo+ICsJdTMyIHJh -dGU7DQo+ICsJdTMyIGlkaXY7DQo+ICsJdTMyIGZiZGl2Ow0KPiArCXUzMiBvZGl2Ow0KPiArfTsN -Cj4gKw0KPiArc3RydWN0IHBsbF9vZl90YWJsZSB7DQo+ICsJdW5zaWduZWQgbG9uZyBwcmF0ZTsN -Cj4gKwlzdHJ1Y3QgcGxsX2NmZyAqcGxsX2NmZ190YWJsZTsNCj4gK307DQo+ICsNCj4gK3N0cnVj -dCBwbGxfb2ZfZGF0YSB7DQo+ICsJc3RydWN0IHBsbF9vZl90YWJsZSAqcGxsX3RhYmxlOw0KPiAr -fTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2ZfZGF0YSBwZ3VfcGxsX2RhdGEgPSB7DQo+ -ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3RhYmxlIFtdKXsNCj4gKwkJew0KPiArCQkJ -LnByYXRlID0gMjcwMDAwMDAsDQo+ICsJCQkucGxsX2NmZ190YWJsZSA9IChzdHJ1Y3QgcGxsX2Nm -ZyBbXSl7DQo+ICsJCQkJeyAyNTIwMDAwMCwgMSwgODQsIDkwIH0sDQo+ICsJCQkJeyA1MDAwMDAw -MCwgMSwgMTAwLCA1NCB9LA0KPiArCQkJCXsgNzQyNTAwMDAsIDEsIDQ0LCAxNiB9LA0KPiArCQkJ -CXsgfSwNCj4gKwkJCX0sDQo+ICsJCX0sDQo+ICsJCS8qIFVzZWQgYXMgbGlzdCBsaW1pdGVyICov -DQo+ICsJCXsgfSwNCj4gKwl9LA0KPiArfTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2Zf -ZGF0YSBhcmNfcGxsX2RhdGEgPSB7DQo+ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3Rh -YmxlIFtdKXsNCj4gKwkJew0KPiArCQkJLnByYXRlID0gMzMzMzMzMzMsDQo+ICsJCQkucGxsX2Nm -Z190YWJsZSA9IChzdHJ1Y3QgcGxsX2NmZyBbXSl7DQo+ICsJCQkJeyAzMzMzMzMzMyzCoMKgMSwg -MSzCoMKgMSB9LA0KPiArCQkJCXsgNTAwMDAwMDAswqDCoDEsIDMwLCAyMCB9LA0KPiArCQkJCXsg -NzUwMDAwMDAswqDCoDIsIDQ1LCAxMCB9LA0KPiArCQkJCXsgOTAwMDAwMDAswqDCoDIsIDU0LCAx -MCB9LA0KPiArCQkJCXsgMTAwMDAwMDAwLCAxLCAzMCwgMTAgfSwNCj4gKwkJCQl7IDEyNTAwMDAw -MCwgMiwgNDUsIDYgfSwNCj4gKwkJCQl7IH0sDQo+ICsJCQl9LA0KPiArCQl9LA0KPiArCQkvKiBV -c2VkIGFzIGxpc3QgbGltaXRlciAqLw0KPiArCQl7IH0sDQo+ICsJfSwNCj4gK307DQo+ICsNCj4g -K3N0cnVjdCBwbGxfY2xrIHsNCj4gKwl2b2lkIF9faW9tZW0gKmJhc2U7DQo+ICsJdm9pZCBfX2lv -bWVtICpsb2NrOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfb2ZfZGF0YSAqcGxsX2RhdGE7DQo+ICsJ -c3RydWN0IGNsa19odyBodzsNCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7DQo+ICt9Ow0KPiArDQo+ -ICtzdGF0aWMgaW5saW5lIHZvaWQgcGxsX3dyaXRlKHN0cnVjdCBwbGxfY2xrICpjbGssIHVuc2ln -bmVkIGludCByZWcsDQo+ICsJCXVuc2lnbmVkIGludCB2YWwpDQo+ICt7DQo+ICsJaW93cml0ZTMy -KHZhbCwgY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiArc3RhdGljIGlubGluZSB1MzIg -cGxsX3JlYWQoc3RydWN0IHBsbF9jbGsgKmNsaywNCj4gKwkJdW5zaWduZWQgaW50IHJlZykNCj4g -K3sNCj4gKwlyZXR1cm4gaW9yZWFkMzIoY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiAr -c3RhdGljIGlubGluZSBzdHJ1Y3QgcGxsX2NsayAqdG9fcGxsX2NsayhzdHJ1Y3QgY2xrX2h3ICpo -dykNCj4gK3sNCj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGh3LCBzdHJ1Y3QgcGxsX2NsaywgaHcp -Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBkaXZfZ2V0X3ZhbHVlKHVuc2lnbmVk -IGludCByZWcpDQo+ICt7DQo+ICsJaWYgKFBMTF9SRUdfR0VUX0JZUEFTUyhyZWcpKQ0KPiArCQly -ZXR1cm4gMTsNCj4gKw0KPiArCXJldHVybiAoUExMX1JFR19HRVRfSElHSChyZWcpICsgUExMX1JF -R19HRVRfTE9XKHJlZykpOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBlbmNvZGVf -ZGl2KHVuc2lnbmVkIGludCBpZCwgaW50IHVwZCkNCj4gK3sNCj4gKwl1aW50MzJfdCBkaXYgPSAw -Ow0KPiArDQo+ICsJUExMX1JFR19TRVRfTE9XKGRpdiwgKGlkJTIgPT0gMCkgPyBpZCA+PiAxIDog -KGlkID4+IDEpICsgMSk7DQo+ICsJUExMX1JFR19TRVRfSElHSChkaXYsIGlkID4+IDEpOw0KPiAr -CVBMTF9SRUdfU0VUX0VER0UoZGl2LCBpZCUyKTsNCj4gKwlQTExfUkVHX1NFVF9CWVBBU1MoZGl2 -LCBpZCA9PSAxID8gMSA6IDApOw0KPiArCVBMTF9SRUdfU0VUX05PVVBEKGRpdiwgIXVwZCk7DQo+ -ICsNCj4gKwlyZXR1cm4gZGl2Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHBs -bF9jZmcgKnBsbF9nZXRfY2ZnKHVuc2lnbmVkIGxvbmcgcHJhdGUsDQo+ICsJCWNvbnN0IHN0cnVj -dCBwbGxfb2ZfdGFibGUgKnBsbF90YWJsZSkNCj4gK3sNCj4gKwlpbnQgaTsNCj4gKw0KPiArCWZv -ciAoaSA9IDA7IHBsbF90YWJsZVtpXS5wcmF0ZSAhPSAwOyBpKyspDQo+ICsJCWlmIChwbGxfdGFi -bGVbaV0ucHJhdGUgPT0gcHJhdGUpDQo+ICsJCQlyZXR1cm4gcGxsX3RhYmxlW2ldLnBsbF9jZmdf -dGFibGU7DQo+ICsNCj4gKwlyZXR1cm4gTlVMTDsNCj4gK30NCj4gKw0KPiArc3RhdGljIHVuc2ln -bmVkIGxvbmcgcGxsX3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LA0KPiArCQkJdW5zaWdu -ZWQgbG9uZyBwYXJlbnRfcmF0ZSkNCj4gK3sNCj4gKwl1NjQgcmF0ZTsNCj4gKwl1MzIgaWRpdiwg -ZmJkaXYsIG9kaXY7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcpOw0K -PiArDQo+ICsJaWRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0lESVYp -KTsNCj4gKwlmYmRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0ZCRElW -KSk7DQo+ICsJb2RpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX09ESVYp -KTsNCj4gKw0KPiArCXJhdGUgPSAodTY0KXBhcmVudF9yYXRlICogZmJkaXY7DQo+ICsJZG9fZGl2 -KHJhdGUsIGlkaXYgKiBvZGl2KTsNCj4gKw0KPiArCXJldHVybiAodW5zaWduZWQgbG9uZylyYXRl -Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgbG9uZyBwbGxfcm91bmRfcmF0ZShzdHJ1Y3QgY2xrX2h3 -ICpodywgdW5zaWduZWQgbG9uZyByYXRlLA0KPiArCQkJdW5zaWduZWQgbG9uZyAqcHJhdGUpDQo+ -ICt7DQo+ICsJaW50IGk7DQo+ICsJbG9uZyBiZXN0X3JhdGU7DQo+ICsJc3RydWN0IHBsbF9jbGsg -KmNsayA9IHRvX3BsbF9jbGsoaHcpOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2Zn -ID0gcGxsX2dldF9jZmcoKnByYXRlLA0KPiArCQkJY2xrLT5wbGxfZGF0YS0+cGxsX3RhYmxlKTsN -Cj4gKw0KPiArCWlmICghcGxsX2NmZykgew0KPiArCQlkZXZfZXJyKGNsay0+ZGV2LCAiaW52YWxp -ZCBwYXJlbnQgcmF0ZT0lbGRcbiIsICpwcmF0ZSk7DQo+ICsJCXJldHVybiAtRUlOVkFMOw0KPiAr -CX0NCj4gKw0KPiArCWlmIChwbGxfY2ZnWzBdLnJhdGUgPT0gMCkNCj4gKwkJcmV0dXJuIC1FSU5W -QUw7DQo+ICsNCj4gKwliZXN0X3JhdGUgPSBwbGxfY2ZnWzBdLnJhdGU7DQo+ICsNCj4gKwlmb3Ig -KGkgPSAxOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChhYnMocmF0ZSAt -IHBsbF9jZmdbaV0ucmF0ZSkgPCBhYnMocmF0ZSAtIGJlc3RfcmF0ZSkpDQo+ICsJCQliZXN0X3Jh -dGUgPSBwbGxfY2ZnW2ldLnJhdGU7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIGJlc3RfcmF0ZTsN -Cj4gK30NCj4gKw0KPiArc3RhdGljIGludCBwbGxfc2V0X3JhdGUoc3RydWN0IGNsa19odyAqaHcs -IHVuc2lnbmVkIGxvbmcgcmF0ZSwNCj4gKwkJCXVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpDQo+ -ICt7DQo+ICsJaW50IGk7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcp -Ow0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2ZnID0gcGxsX2dldF9jZmcocGFyZW50 -X3JhdGUsDQo+ICsJCQljbGstPnBsbF9kYXRhLT5wbGxfdGFibGUpOw0KPiArDQo+ICsJaWYgKCFw -bGxfY2ZnKSB7DQo+ICsJCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHBhcmVudCByYXRlPSVs -ZFxuIiwgcGFyZW50X3JhdGUpOw0KPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gKwl9DQo+ICsNCj4g -Kwlmb3IgKGkgPSAwOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChwbGxf -Y2ZnW2ldLnJhdGUgPT0gcmF0ZSkgew0KPiArCQkJcGxsX3dyaXRlKGNsaywgUExMX1JFR19JRElW -LA0KPiArCQkJCQllbmNvZGVfZGl2KHBsbF9jZmdbaV0uaWRpdiwgMCkpOw0KPiArCQkJcGxsX3dy -aXRlKGNsaywgUExMX1JFR19GQkRJViwNCj4gKwkJCQkJZW5jb2RlX2RpdihwbGxfY2ZnW2ldLmZi -ZGl2LCAwKSk7DQo+ICsJCQlwbGxfd3JpdGUoY2xrLCBQTExfUkVHX09ESVYsDQo+ICsJCQkJCWVu -Y29kZV9kaXYocGxsX2NmZ1tpXS5vZGl2LCAxKSk7DQo+ICsNCj4gKwkJCS8qDQo+ICsJCQnCoCog -V2FpdCB1bnRpbCBDR1UgcmVsb2Nrcy4NCj4gKwkJCcKgKiBJZiBhZnRlciB0aW1lb3V0IENHVSBp -cyB1bmxvY2tlZCB5ZXQgcmV0dXJuIGVycm9yDQo+ICsJCQnCoCovDQo+ICsJCQl1ZGVsYXkoUExM -X01BWF9MT0NLX1RJTUUpOw0KPiArCQkJaWYgKGlvcmVhZDMyKGNsay0+bG9jaykgJiBQTExfTE9D -SykNCj4gKwkJCQlyZXR1cm4gMDsNCj4gKwkJCWVsc2UNCj4gKwkJCQlyZXR1cm4gLUVUSU1FRE9V -VDsNCj4gKwkJfQ0KPiArCX0NCj4gKw0KPiArCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHJh -dGU9JWxkLCBwYXJlbnRfcmF0ZT0lbGRcbiIsIHJhdGUsDQo+ICsJCQlwYXJlbnRfcmF0ZSk7DQo+ -ICsJcmV0dXJuIC1FSU5WQUw7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY2xr -X29wcyBwbGxfb3BzID0gew0KPiArCS5yZWNhbGNfcmF0ZSA9IHBsbF9yZWNhbGNfcmF0ZSwNCj4g -Kwkucm91bmRfcmF0ZSA9IHBsbF9yb3VuZF9yYXRlLA0KPiArCS5zZXRfcmF0ZSA9IHBsbF9zZXRf -cmF0ZSwNCj4gK307DQo+ICsNCj4gK3N0YXRpYyBpbnQgcGxsX2Nsa19wcm9iZShzdHJ1Y3QgcGxh -dGZvcm1fZGV2aWNlICpwZGV2KQ0KPiArew0KPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2 -LT5kZXY7DQo+ICsJY29uc3QgY2hhciAqcGFyZW50X25hbWU7DQo+ICsJc3RydWN0IGNsayAqY2xr -Ow0KPiArCXN0cnVjdCBwbGxfY2xrICpwbGxfY2xrOw0KPiArCXN0cnVjdCByZXNvdXJjZSAqbWVt -Ow0KPiArCXN0cnVjdCBjbGtfaW5pdF9kYXRhIGluaXQgPSB7IH07DQo+ICsNCj4gKwlwbGxfY2xr -ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJ -aWYgKCFwbGxfY2xrKQ0KPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gKw0KPiArCW1lbSA9IHBsYXRm -b3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7DQo+ICsJcGxsX2Nsay0+ -YmFzZSA9IGRldm1faW9yZW1hcF9yZXNvdXJjZShkZXYsIG1lbSk7DQo+ICsJaWYgKElTX0VSUihw -bGxfY2xrLT5iYXNlKSkNCj4gKwkJcmV0dXJuIFBUUl9FUlIocGxsX2Nsay0+YmFzZSk7DQo+ICsN -Cj4gKwltZW0gPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDEp -Ow0KPiArCXBsbF9jbGstPmxvY2sgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCBtZW0pOw0K -PiArCWlmIChJU19FUlIocGxsX2Nsay0+bG9jaykpDQo+ICsJCXJldHVybiBQVFJfRVJSKHBsbF9j -bGstPmJhc2UpOw0KPiArDQo+ICsJaW5pdC5uYW1lID0gZGV2LT5vZl9ub2RlLT5uYW1lOw0KPiAr -CWluaXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVu -dF9uYW1lKGRldi0+b2Zfbm9kZSwgMCk7DQo+ICsJaW5pdC5wYXJlbnRfbmFtZXMgPSAmcGFyZW50 -X25hbWU7DQo+ICsJaW5pdC5udW1fcGFyZW50cyA9IDE7DQo+ICsJcGxsX2Nsay0+aHcuaW5pdCA9 -ICZpbml0Ow0KPiArCXBsbF9jbGstPmRldiA9IGRldjsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9 -IG9mX2RldmljZV9nZXRfbWF0Y2hfZGF0YShkZXYpOw0KPiArDQo+ICsJaWYgKCFwbGxfY2xrLT5w -bGxfZGF0YSkgew0KPiArCQlkZXZfZXJyKGRldiwgIk5vIE9GIG1hdGNoIGRhdGEgcHJvdmlkZWRc -biIpOw0KPiArCQkJcmV0dXJuIC1FSU5WQUw7DQo+ICsJfQ0KPiArDQo+ICsJY2xrID0gZGV2bV9j -bGtfcmVnaXN0ZXIoZGV2LCAmcGxsX2Nsay0+aHcpOw0KPiArCWlmIChJU19FUlIoY2xrKSkgew0K -PiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byByZWdpc3RlciAlcyBjbG9jayAoJWxkKVxuIiwN -Cj4gKwkJCQlpbml0Lm5hbWUsIFBUUl9FUlIoY2xrKSk7DQo+ICsJCXJldHVybiBQVFJfRVJSKGNs -ayk7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIG9mX2Nsa19hZGRfcHJvdmlkZXIoZGV2LT5vZl9u -b2RlLCBvZl9jbGtfc3JjX3NpbXBsZV9nZXQsIGNsayk7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBp -bnQgcGxsX2Nsa19yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gK3sNCj4g -KwlvZl9jbGtfZGVsX3Byb3ZpZGVyKHBkZXYtPmRldi5vZl9ub2RlKTsNCj4gKwlyZXR1cm4gMDsN -Cj4gK30NCj4gKw0KPiArc3RhdGljIHZvaWQgX19pbml0IG9mX3BsbF9jbGtfc2V0dXAoc3RydWN0 -IGRldmljZV9ub2RlICpub2RlKQ0KPiArew0KPiArCWNvbnN0IGNoYXIgKnBhcmVudF9uYW1lOw0K -PiArCXN0cnVjdCBjbGsgKmNsazsNCj4gKwlzdHJ1Y3QgcGxsX2NsayAqcGxsX2NsazsNCj4gKwlz -dHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0ID0geyB9Ow0KPiArDQo+ICsJcGxsX2NsayA9IGt6YWxs -b2Moc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJaWYgKCFwbGxfY2xrKQ0KPiAr -CQlyZXR1cm47DQo+ICsNCj4gKwlwbGxfY2xrLT5iYXNlID0gb2ZfaW9tYXAobm9kZSwgMCk7DQo+ -ICsJaWYgKCFwbGxfY2xrLT5iYXNlKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBwbGwg -ZGl2IHJlZ2lzdGVyc1xuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+YmFzZSk7DQo+ICsJCXJl -dHVybjsNCj4gKwl9DQo+ICsNCj4gKwlwbGxfY2xrLT5sb2NrID0gb2ZfaW9tYXAobm9kZSwgMSk7 -DQo+ICsJaWYgKCFwbGxfY2xrLT5sb2NrKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBw -bGwgbG9jayByZWdpc3RlclxuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+bG9jayk7DQo+ICsJ -CXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlpbml0Lm5hbWUgPSBub2RlLT5uYW1lOw0KPiArCWlu -aXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVudF9u -YW1lKG5vZGUsIDApOw0KPiArCWluaXQucGFyZW50X25hbWVzID0gJnBhcmVudF9uYW1lOw0KPiAr -CWluaXQubnVtX3BhcmVudHMgPSBwYXJlbnRfbmFtZSA/IDEgOiAwOw0KPiArCXBsbF9jbGstPmh3 -LmluaXQgPSAmaW5pdDsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9ICZhcmNfcGxsX2RhdGE7DQo+ -ICsNCj4gKwljbGsgPSBjbGtfcmVnaXN0ZXIoTlVMTCwgJnBsbF9jbGstPmh3KTsNCj4gKwlpZiAo -SVNfRVJSKGNsaykpIHsNCj4gKwkJcHJfZXJyKCJmYWlsZWQgdG8gcmVnaXN0ZXIgJXMgY2xvY2sg -KCVsZClcbiIsDQo+ICsJCQkJbm9kZS0+bmFtZSwgUFRSX0VSUihjbGspKTsNCj4gKwkJa2ZyZWUo -cGxsX2Nsayk7DQo+ICsJCXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlvZl9jbGtfYWRkX3Byb3Zp -ZGVyKG5vZGUsIG9mX2Nsa19zcmNfc2ltcGxlX2dldCwgY2xrKTsNCj4gK30NCj4gKw0KPiArQ0xL -X09GX0RFQ0xBUkUoYXhzMTB4X3BsbF9jbG9jaywgInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2si -LCBvZl9wbGxfY2xrX3NldHVwKTsNCj4gKw0KPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp -Y2VfaWQgcGxsX2Nsa19pZFtdID0gew0KPiArCXsgLmNvbXBhdGlibGUgPSAic25wcyxheHMxMHgt -YXJjLXBsbC1jbG9jayIsIC5kYXRhID0gJmFyY19wbGxfZGF0YX0sDQo+ICsJeyAuY29tcGF0aWJs -ZSA9ICJzbnBzLGF4czEweC1wZ3UtcGxsLWNsb2NrIiwgLmRhdGEgPSAmcGd1X3BsbF9kYXRhfSwN -Cj4gKwl7IH0sDQo+ICt9Ow0KPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgcGxsX2Nsa19pZCk7 -DQo+ICsNCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIHBsbF9jbGtfZHJpdmVyID0g -ew0KPiArCS5kcml2ZXIgPSB7DQo+ICsJCS5uYW1lID0gImF4czEweC1wbGwtY2xvY2siLA0KPiAr -CQkub2ZfbWF0Y2hfdGFibGUgPSBwbGxfY2xrX2lkLA0KPiArCX0sDQo+ICsJLnByb2JlID0gcGxs -X2Nsa19wcm9iZSwNCj4gKwkucmVtb3ZlID0gcGxsX2Nsa19yZW1vdmUsDQo+ICt9Ow0KPiArYnVp -bHRpbl9wbGF0Zm9ybV9kcml2ZXIocGxsX2Nsa19kcml2ZXIpOw0KPiArDQo+ICtNT0RVTEVfQVVU -SE9SKCJWbGFkIFpha2hhcm92IDx2emFraGFyQHN5bm9wc3lzLmNvbT4iKTsNCj4gK01PRFVMRV9E -RVNDUklQVElPTigiU3lub3BzeXMgQVhTMTBYIFNEUCBHZW5lcmljIFBMTCBDbG9jayBEcml2ZXIi -KTsNCj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsNCg0KTWF5YmUgeW91IGhhdmUgYW55IGNv -bW1lbnRzIG9yIHJlbWFya3MgYWJvdXQgdGhpcyBwYXRjaD8gQW5kIGlmIHlvdSBkb24ndCBjb3Vs -ZCB5b3UgcGxlYXNlIGFwcGx5IGl0Lg0KDQpUaGFua3MhDQoNCi0tIA0KQmVzdCByZWdhcmRzLA0K -VmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+ +Hi Michael, Stephen, + +On Tue, 2017-02-21 at 16:11 +0300, Vlad Zakharov wrote: +> AXS10X boards manages it's clocks using various PLLs. These PLL has same +> dividers and corresponding control registers mapped to different addresses. +> So we add one common driver for such PLLs. +> +> Each PLL on AXS10X board consist of three dividers: IDIV, FBDIV and +> ODIV. Output clock value is managed using these dividers. +> +> We add pre-defined tables with supported rate values and appropriate +> configurations of IDIV, FBDIV and ODIV for each value. +> +> As of today we add support for PLLs that generate clock for the +> following devices: +>  * ARC core on AXC CPU tiles. +>  * ARC PGU on ARC SDP Mainboard. +> and more to come later. +> +> Acked-by: Rob Herring <robh@kernel.org> +> Signed-off-by: Vlad Zakharov <vzakhar@synopsys.com> +> Signed-off-by: Jose Abreu <joabreu@synopsys.com> +> Cc: Michael Turquette <mturquette@baylibre.com> +> Cc: Stephen Boyd <sboyd@codeaurora.org> +> Cc: Mark Rutland <mark.rutland@arm.com> +> --- +> Cc: Rob Herring <robh@kernel.org> +> Changes v1..v2 +>  - Replace '_' with '-' in device tree nodes +> +>  .../devicetree/bindings/clock/snps,pll-clock.txt   |  28 ++ +>  MAINTAINERS                                        |   6 + +>  drivers/clk/axs10x/Makefile                        |   1 + +>  drivers/clk/axs10x/pll_clock.c                     | 384 +++++++++++++++++++++ +>  4 files changed, 419 insertions(+) +>  create mode 100644 Documentation/devicetree/bindings/clock/snps,pll-clock.txt +>  create mode 100644 drivers/clk/axs10x/pll_clock.c +> +> diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> new file mode 100644 +> index 0000000..5706246 +> --- /dev/null +> +++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> @@ -0,0 +1,28 @@ +> +Binding for the AXS10X Generic PLL clock +> + +> +This binding uses the common clock binding[1]. +> + +> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +> + +> +Required properties: +> +- compatible: should be "snps,axs10x-<name>-pll-clock" +> +  "snps,axs10x-arc-pll-clock" +> +  "snps,axs10x-pgu-pll-clock" +> +- reg: should always contain 2 pairs address - length: first for PLL config +> +registers and second for corresponding LOCK CGU register. +> +- clocks: shall be the input parent clock phandle for the PLL. +> +- #clock-cells: from common clock binding; Should always be set to 0. +> + +> +Example: +> + input-clk: input-clk { +> + clock-frequency = <33333333>; +> + compatible = "fixed-clock"; +> + #clock-cells = <0>; +> + }; +> + +> + core-clk: core-clk@80 { +> + compatible = "snps,axs10x-arc-pll-clock"; +> + reg = <0x80 0x10 0x100 0x10>; +> + #clock-cells = <0>; +> + clocks = <&input-clk>; +> + }; +> diff --git a/MAINTAINERS b/MAINTAINERS +> index 3960e7f..5805833 100644 +> --- a/MAINTAINERS +> +++ b/MAINTAINERS +> @@ -11910,6 +11910,12 @@ F: arch/arc/plat-axs10x +>  F: arch/arc/boot/dts/ax* +>  F: Documentation/devicetree/bindings/arc/axs10* +>  +> +SYNOPSYS ARC SDP clock driver +> +M: Vlad Zakharov <vzakhar@synopsys.com> +> +S: Supported +> +F: drivers/clk/axs10x/* +> +F: Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> + +>  SYSTEM CONFIGURATION (SYSCON) +>  M: Lee Jones <lee.jones@linaro.org> +>  M: Arnd Bergmann <arnd@arndb.de> +> diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile +> index 01996b8..d747dea 100644 +> --- a/drivers/clk/axs10x/Makefile +> +++ b/drivers/clk/axs10x/Makefile +> @@ -1 +1,2 @@ +>  obj-y += i2s_pll_clock.o +> +obj-y += pll_clock.o +> diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c +> new file mode 100644 +> index 0000000..784a0a2 +> --- /dev/null +> +++ b/drivers/clk/axs10x/pll_clock.c +> @@ -0,0 +1,384 @@ +> +/* +> + * Synopsys AXS10X SDP Generic PLL clock driver +> + * +> + * Copyright (C) 2017 Synopsys +> + * +> + * This file is licensed under the terms of the GNU General Public +> + * License version 2. This program is licensed "as is" without any +> + * warranty of any kind, whether express or implied. +> + */ +> + +> +#include <linux/platform_device.h> +> +#include <linux/module.h> +> +#include <linux/clk-provider.h> +> +#include <linux/delay.h> +> +#include <linux/err.h> +> +#include <linux/device.h> +> +#include <linux/of_address.h> +> +#include <linux/of_device.h> +> +#include <linux/slab.h> +> +#include <linux/of.h> +> + +> +/* PLL registers addresses */ +> +#define PLL_REG_IDIV 0x0 +> +#define PLL_REG_FBDIV 0x4 +> +#define PLL_REG_ODIV 0x8 +> + +> +/* +> + * Bit fields of the PLL IDIV/FBDIV/ODIV registers: +> + *  ________________________________________________________________________ +> + * |31                15|    14    |   13   |  12  |11         6|5         0| +> + * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--| +> + * |____________________|__________|________|______|____________|___________| +> + * +> + * Following macros detirmine the way of access to these registers +> + * They should be set up only using the macros. +> + * reg should be and uint32_t variable. +> + */ +> + +> +#define PLL_REG_GET_LOW(reg) \ +> + (((reg) & (0x3F << 0)) >> 0) +> +#define PLL_REG_GET_HIGH(reg) \ +> + (((reg) & (0x3F << 6)) >> 6) +> +#define PLL_REG_GET_EDGE(reg) \ +> + (((reg) & (BIT(12))) ? 1 : 0) +> +#define PLL_REG_GET_BYPASS(reg) \ +> + (((reg) & (BIT(13))) ? 1 : 0) +> +#define PLL_REG_GET_NOUPD(reg) \ +> + (((reg) & (BIT(14))) ? 1 : 0) +> +#define PLL_REG_GET_PAD(reg) \ +> + (((reg) & (0x1FFFF << 15)) >> 15) +> + +> +#define PLL_REG_SET_LOW(reg, value) \ +> + { reg |= (((value) & 0x3F) << 0); } +> +#define PLL_REG_SET_HIGH(reg, value) \ +> + { reg |= (((value) & 0x3F) << 6); } +> +#define PLL_REG_SET_EDGE(reg, value) \ +> + { reg |= (((value) & 0x01) << 12); } +> +#define PLL_REG_SET_BYPASS(reg, value) \ +> + { reg |= (((value) & 0x01) << 13); } +> +#define PLL_REG_SET_NOUPD(reg, value) \ +> + { reg |= (((value) & 0x01) << 14); } +> +#define PLL_REG_SET_PAD(reg, value) \ +> + { reg |= (((value) & 0x1FFFF) << 15); } +> + +> +#define PLL_LOCK 0x1 +> +#define PLL_MAX_LOCK_TIME 100 /* 100 us */ +> + +> +struct pll_cfg { +> + u32 rate; +> + u32 idiv; +> + u32 fbdiv; +> + u32 odiv; +> +}; +> + +> +struct pll_of_table { +> + unsigned long prate; +> + struct pll_cfg *pll_cfg_table; +> +}; +> + +> +struct pll_of_data { +> + struct pll_of_table *pll_table; +> +}; +> + +> +static struct pll_of_data pgu_pll_data = { +> + .pll_table = (struct pll_of_table []){ +> + { +> + .prate = 27000000, +> + .pll_cfg_table = (struct pll_cfg []){ +> + { 25200000, 1, 84, 90 }, +> + { 50000000, 1, 100, 54 }, +> + { 74250000, 1, 44, 16 }, +> + { }, +> + }, +> + }, +> + /* Used as list limiter */ +> + { }, +> + }, +> +}; +> + +> +static struct pll_of_data arc_pll_data = { +> + .pll_table = (struct pll_of_table []){ +> + { +> + .prate = 33333333, +> + .pll_cfg_table = (struct pll_cfg []){ +> + { 33333333,  1, 1,  1 }, +> + { 50000000,  1, 30, 20 }, +> + { 75000000,  2, 45, 10 }, +> + { 90000000,  2, 54, 10 }, +> + { 100000000, 1, 30, 10 }, +> + { 125000000, 2, 45, 6 }, +> + { }, +> + }, +> + }, +> + /* Used as list limiter */ +> + { }, +> + }, +> +}; +> + +> +struct pll_clk { +> + void __iomem *base; +> + void __iomem *lock; +> + const struct pll_of_data *pll_data; +> + struct clk_hw hw; +> + struct device *dev; +> +}; +> + +> +static inline void pll_write(struct pll_clk *clk, unsigned int reg, +> + unsigned int val) +> +{ +> + iowrite32(val, clk->base + reg); +> +} +> + +> +static inline u32 pll_read(struct pll_clk *clk, +> + unsigned int reg) +> +{ +> + return ioread32(clk->base + reg); +> +} +> + +> +static inline struct pll_clk *to_pll_clk(struct clk_hw *hw) +> +{ +> + return container_of(hw, struct pll_clk, hw); +> +} +> + +> +static inline u32 div_get_value(unsigned int reg) +> +{ +> + if (PLL_REG_GET_BYPASS(reg)) +> + return 1; +> + +> + return (PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg)); +> +} +> + +> +static inline u32 encode_div(unsigned int id, int upd) +> +{ +> + uint32_t div = 0; +> + +> + PLL_REG_SET_LOW(div, (id%2 == 0) ? id >> 1 : (id >> 1) + 1); +> + PLL_REG_SET_HIGH(div, id >> 1); +> + PLL_REG_SET_EDGE(div, id%2); +> + PLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0); +> + PLL_REG_SET_NOUPD(div, !upd); +> + +> + return div; +> +} +> + +> +static const struct pll_cfg *pll_get_cfg(unsigned long prate, +> + const struct pll_of_table *pll_table) +> +{ +> + int i; +> + +> + for (i = 0; pll_table[i].prate != 0; i++) +> + if (pll_table[i].prate == prate) +> + return pll_table[i].pll_cfg_table; +> + +> + return NULL; +> +} +> + +> +static unsigned long pll_recalc_rate(struct clk_hw *hw, +> + unsigned long parent_rate) +> +{ +> + u64 rate; +> + u32 idiv, fbdiv, odiv; +> + struct pll_clk *clk = to_pll_clk(hw); +> + +> + idiv = div_get_value(pll_read(clk, PLL_REG_IDIV)); +> + fbdiv = div_get_value(pll_read(clk, PLL_REG_FBDIV)); +> + odiv = div_get_value(pll_read(clk, PLL_REG_ODIV)); +> + +> + rate = (u64)parent_rate * fbdiv; +> + do_div(rate, idiv * odiv); +> + +> + return (unsigned long)rate; +> +} +> + +> +static long pll_round_rate(struct clk_hw *hw, unsigned long rate, +> + unsigned long *prate) +> +{ +> + int i; +> + long best_rate; +> + struct pll_clk *clk = to_pll_clk(hw); +> + const struct pll_cfg *pll_cfg = pll_get_cfg(*prate, +> + clk->pll_data->pll_table); +> + +> + if (!pll_cfg) { +> + dev_err(clk->dev, "invalid parent rate=%ld\n", *prate); +> + return -EINVAL; +> + } +> + +> + if (pll_cfg[0].rate == 0) +> + return -EINVAL; +> + +> + best_rate = pll_cfg[0].rate; +> + +> + for (i = 1; pll_cfg[i].rate != 0; i++) { +> + if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) +> + best_rate = pll_cfg[i].rate; +> + } +> + +> + return best_rate; +> +} +> + +> +static int pll_set_rate(struct clk_hw *hw, unsigned long rate, +> + unsigned long parent_rate) +> +{ +> + int i; +> + struct pll_clk *clk = to_pll_clk(hw); +> + const struct pll_cfg *pll_cfg = pll_get_cfg(parent_rate, +> + clk->pll_data->pll_table); +> + +> + if (!pll_cfg) { +> + dev_err(clk->dev, "invalid parent rate=%ld\n", parent_rate); +> + return -EINVAL; +> + } +> + +> + for (i = 0; pll_cfg[i].rate != 0; i++) { +> + if (pll_cfg[i].rate == rate) { +> + pll_write(clk, PLL_REG_IDIV, +> + encode_div(pll_cfg[i].idiv, 0)); +> + pll_write(clk, PLL_REG_FBDIV, +> + encode_div(pll_cfg[i].fbdiv, 0)); +> + pll_write(clk, PLL_REG_ODIV, +> + encode_div(pll_cfg[i].odiv, 1)); +> + +> + /* +> +  * Wait until CGU relocks. +> +  * If after timeout CGU is unlocked yet return error +> +  */ +> + udelay(PLL_MAX_LOCK_TIME); +> + if (ioread32(clk->lock) & PLL_LOCK) +> + return 0; +> + else +> + return -ETIMEDOUT; +> + } +> + } +> + +> + dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate, +> + parent_rate); +> + return -EINVAL; +> +} +> + +> +static const struct clk_ops pll_ops = { +> + .recalc_rate = pll_recalc_rate, +> + .round_rate = pll_round_rate, +> + .set_rate = pll_set_rate, +> +}; +> + +> +static int pll_clk_probe(struct platform_device *pdev) +> +{ +> + struct device *dev = &pdev->dev; +> + const char *parent_name; +> + struct clk *clk; +> + struct pll_clk *pll_clk; +> + struct resource *mem; +> + struct clk_init_data init = { }; +> + +> + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); +> + if (!pll_clk) +> + return -ENOMEM; +> + +> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +> + pll_clk->base = devm_ioremap_resource(dev, mem); +> + if (IS_ERR(pll_clk->base)) +> + return PTR_ERR(pll_clk->base); +> + +> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); +> + pll_clk->lock = devm_ioremap_resource(dev, mem); +> + if (IS_ERR(pll_clk->lock)) +> + return PTR_ERR(pll_clk->base); +> + +> + init.name = dev->of_node->name; +> + init.ops = &pll_ops; +> + parent_name = of_clk_get_parent_name(dev->of_node, 0); +> + init.parent_names = &parent_name; +> + init.num_parents = 1; +> + pll_clk->hw.init = &init; +> + pll_clk->dev = dev; +> + pll_clk->pll_data = of_device_get_match_data(dev); +> + +> + if (!pll_clk->pll_data) { +> + dev_err(dev, "No OF match data provided\n"); +> + return -EINVAL; +> + } +> + +> + clk = devm_clk_register(dev, &pll_clk->hw); +> + if (IS_ERR(clk)) { +> + dev_err(dev, "failed to register %s clock (%ld)\n", +> + init.name, PTR_ERR(clk)); +> + return PTR_ERR(clk); +> + } +> + +> + return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, clk); +> +} +> + +> +static int pll_clk_remove(struct platform_device *pdev) +> +{ +> + of_clk_del_provider(pdev->dev.of_node); +> + return 0; +> +} +> + +> +static void __init of_pll_clk_setup(struct device_node *node) +> +{ +> + const char *parent_name; +> + struct clk *clk; +> + struct pll_clk *pll_clk; +> + struct clk_init_data init = { }; +> + +> + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); +> + if (!pll_clk) +> + return; +> + +> + pll_clk->base = of_iomap(node, 0); +> + if (!pll_clk->base) { +> + pr_err("failed to map pll div registers\n"); +> + iounmap(pll_clk->base); +> + return; +> + } +> + +> + pll_clk->lock = of_iomap(node, 1); +> + if (!pll_clk->lock) { +> + pr_err("failed to map pll lock register\n"); +> + iounmap(pll_clk->lock); +> + return; +> + } +> + +> + init.name = node->name; +> + init.ops = &pll_ops; +> + parent_name = of_clk_get_parent_name(node, 0); +> + init.parent_names = &parent_name; +> + init.num_parents = parent_name ? 1 : 0; +> + pll_clk->hw.init = &init; +> + pll_clk->pll_data = &arc_pll_data; +> + +> + clk = clk_register(NULL, &pll_clk->hw); +> + if (IS_ERR(clk)) { +> + pr_err("failed to register %s clock (%ld)\n", +> + node->name, PTR_ERR(clk)); +> + kfree(pll_clk); +> + return; +> + } +> + +> + of_clk_add_provider(node, of_clk_src_simple_get, clk); +> +} +> + +> +CLK_OF_DECLARE(axs10x_pll_clock, "snps,axs10x-arc-pll-clock", of_pll_clk_setup); +> + +> +static const struct of_device_id pll_clk_id[] = { +> + { .compatible = "snps,axs10x-arc-pll-clock", .data = &arc_pll_data}, +> + { .compatible = "snps,axs10x-pgu-pll-clock", .data = &pgu_pll_data}, +> + { }, +> +}; +> +MODULE_DEVICE_TABLE(of, pll_clk_id); +> + +> +static struct platform_driver pll_clk_driver = { +> + .driver = { +> + .name = "axs10x-pll-clock", +> + .of_match_table = pll_clk_id, +> + }, +> + .probe = pll_clk_probe, +> + .remove = pll_clk_remove, +> +}; +> +builtin_platform_driver(pll_clk_driver); +> + +> +MODULE_AUTHOR("Vlad Zakharov <vzakhar@synopsys.com>"); +> +MODULE_DESCRIPTION("Synopsys AXS10X SDP Generic PLL Clock Driver"); +> +MODULE_LICENSE("GPL v2"); + +Maybe you have any comments or remarks about this patch? And if you don't could you please apply it. + +Thanks! + +-- +Best regards, +Vlad Zakharov <vzakhar@synopsys.com>N§²æìr¸yúèØb²X¬¶Ç§vØ^)Þº{.nÇ+·zøzÚÞz)í æèw*\x1fjg¬±¨\x1e¶Ý¢j.ïÛ°\½½MúgjÌæa×\x02' ©Þ¢¸\f¢·¦j:+v¨wèjØm¶ÿ¾\a«êçzZ+ùÝ¢j"ú!¶i diff --git a/a/content_digest b/N2/content_digest index e97820e..3db0f5d 100644 --- a/a/content_digest +++ b/N2/content_digest @@ -1,284 +1,513 @@ "ref\01487682670-4164-1-git-send-email-vzakhar@synopsys.com\0" - "From\0Vlad Zakharov <Vladislav.Zakharov@synopsys.com>\0" + "ref\01487682670-4164-1-git-send-email-vzakhar-HKixBCOQz3hWk0Htik3J/w@public.gmane.org\0" + "From\0Vlad Zakharov <Vladislav.Zakharov-HKixBCOQz3hWk0Htik3J/w@public.gmane.org>\0" "Subject\0Re: [PATCH v2] clk/axs10x: introduce AXS10X pll driver\0" "Date\0Fri, 3 Mar 2017 13:18:34 +0000\0" - "To\0Michael Turquette <mturquette@baylibre.com>" - " Stephen Boyd <sboyd@codeaurora.org>\0" - "Cc\0linux-kernel@vger.kernel.org <linux-kernel@vger.kernel.org>" - mturquette@baylibre.com <mturquette@baylibre.com> - Jose Abreu <Jose.Abreu@synopsys.com> - devicetree@vger.kernel.org <devicetree@vger.kernel.org> - linux-snps-arc@lists.infradead.org <linux-snps-arc@lists.infradead.org> - mark.rutland@arm.com <mark.rutland@arm.com> - robh@kernel.org <robh@kernel.org> - linux-clk@vger.kernel.org <linux-clk@vger.kernel.org> - " sboyd@codeaurora.org <sboyd@codeaurora.org>\0" + "Cc\0linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>" + mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org <mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> + Jose Abreu <Jose.Abreu-HKixBCOQz3hWk0Htik3J/w@public.gmane.org> + devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org <devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org> + linux-snps-arc-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org <linux-snps-arc-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org> + mark.rutland-5wv7dgnIgG8@public.gmane.org <mark.rutland-5wv7dgnIgG8@public.gmane.org> + robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> + linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org <linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org> + " sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>\0" "\00:1\0" "b\0" - "SGkgTWljaGFlbCwgU3RlcGhlbiwNCg0KT24gVHVlLCAyMDE3LTAyLTIxIGF0IDE2OjExICswMzAw\n" - "LCBWbGFkIFpha2hhcm92IHdyb3RlOg0KPiBBWFMxMFggYm9hcmRzIG1hbmFnZXMgaXQncyBjbG9j\n" - "a3MgdXNpbmcgdmFyaW91cyBQTExzLiBUaGVzZSBQTEwgaGFzIHNhbWUNCj4gZGl2aWRlcnMgYW5k\n" - "IGNvcnJlc3BvbmRpbmcgY29udHJvbCByZWdpc3RlcnMgbWFwcGVkIHRvIGRpZmZlcmVudCBhZGRy\n" - "ZXNzZXMuDQo+IFNvIHdlIGFkZCBvbmUgY29tbW9uIGRyaXZlciBmb3Igc3VjaCBQTExzLg0KPiAN\n" - "Cj4gRWFjaCBQTEwgb24gQVhTMTBYIGJvYXJkIGNvbnNpc3Qgb2YgdGhyZWUgZGl2aWRlcnM6IElE\n" - "SVYsIEZCRElWIGFuZA0KPiBPRElWLiBPdXRwdXQgY2xvY2sgdmFsdWUgaXMgbWFuYWdlZCB1c2lu\n" - "ZyB0aGVzZSBkaXZpZGVycy4NCj4gDQo+IFdlIGFkZCBwcmUtZGVmaW5lZCB0YWJsZXMgd2l0aCBz\n" - "dXBwb3J0ZWQgcmF0ZSB2YWx1ZXMgYW5kIGFwcHJvcHJpYXRlDQo+IGNvbmZpZ3VyYXRpb25zIG9m\n" - "IElESVYsIEZCRElWIGFuZCBPRElWIGZvciBlYWNoIHZhbHVlLg0KPiANCj4gQXMgb2YgdG9kYXkg\n" - "d2UgYWRkIHN1cHBvcnQgZm9yIFBMTHMgdGhhdCBnZW5lcmF0ZSBjbG9jayBmb3IgdGhlDQo+IGZv\n" - "bGxvd2luZyBkZXZpY2VzOg0KPiDCoCogQVJDIGNvcmUgb24gQVhDIENQVSB0aWxlcy4NCj4gwqAq\n" - "IEFSQyBQR1Ugb24gQVJDIFNEUCBNYWluYm9hcmQuDQo+IGFuZCBtb3JlIHRvIGNvbWUgbGF0ZXIu\n" - "DQo+IA0KPiBBY2tlZC1ieTogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gU2lnbmVk\n" - "LW9mZi1ieTogVmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+DQo+IFNpZ25lZC1v\n" - "ZmYtYnk6IEpvc2UgQWJyZXUgPGpvYWJyZXVAc3lub3BzeXMuY29tPg0KPiBDYzogTWljaGFlbCBU\n" - "dXJxdWV0dGUgPG10dXJxdWV0dGVAYmF5bGlicmUuY29tPg0KPiBDYzogU3RlcGhlbiBCb3lkIDxz\n" - "Ym95ZEBjb2RlYXVyb3JhLm9yZz4NCj4gQ2M6IE1hcmsgUnV0bGFuZCA8bWFyay5ydXRsYW5kQGFy\n" - "bS5jb20+DQo+IC0tLQ0KPiBDYzogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gQ2hh\n" - "bmdlcyB2MS4udjINCj4gwqAtIFJlcGxhY2UgJ18nIHdpdGggJy0nIGluIGRldmljZSB0cmVlIG5v\n" - "ZGVzDQo+IA0KPiDCoC4uLi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxsLWNsb2Nr\n" - "LnR4dMKgwqDCoHzCoMKgMjggKysNCj4gwqBNQUlOVEFJTkVSU8KgwqDCoMKgwqDCoMKgwqDCoMKg\n" - "wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC\n" - "oMKgfMKgwqDCoDYgKw0KPiDCoGRyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZcKgwqDCoMKgwqDC\n" - "oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAxICsNCj4gwqBkcml2\n" - "ZXJzL2Nsay9heHMxMHgvcGxsX2Nsb2NrLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC\n" - "oMKgwqDCoMKgwqB8IDM4NCArKysrKysrKysrKysrKysrKysrKysNCj4gwqA0IGZpbGVzIGNoYW5n\n" - "ZWQsIDQxOSBpbnNlcnRpb25zKCspDQo+IMKgY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp\n" - "b24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gwqBjcmVh\n" - "dGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IA0KPiBkaWZm\n" - "IC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxs\n" - "LWNsb2NrLnR4dA0KPiBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9z\n" - "bnBzLHBsbC1jbG9jay50eHQNCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gaW5kZXggMDAwMDAw\n" - "MC4uNTcwNjI0Ng0KPiAtLS0gL2Rldi9udWxsDQo+ICsrKyBiL0RvY3VtZW50YXRpb24vZGV2aWNl\n" - "dHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gQEAgLTAsMCArMSwyOCBA\n" - "QA0KPiArQmluZGluZyBmb3IgdGhlIEFYUzEwWCBHZW5lcmljIFBMTCBjbG9jaw0KPiArDQo+ICtU\n" - "aGlzIGJpbmRpbmcgdXNlcyB0aGUgY29tbW9uIGNsb2NrIGJpbmRpbmdbMV0uDQo+ICsNCj4gK1sx\n" - "XSBEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvY2xvY2svY2xvY2stYmluZGluZ3Mu\n" - "dHh0DQo+ICsNCj4gK1JlcXVpcmVkIHByb3BlcnRpZXM6DQo+ICstIGNvbXBhdGlibGU6IHNob3Vs\n" - "ZCBiZSAic25wcyxheHMxMHgtPG5hbWU+LXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgt\n" - "YXJjLXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgtcGd1LXBsbC1jbG9jayINCj4gKy0g\n" - "cmVnOiBzaG91bGQgYWx3YXlzIGNvbnRhaW4gMiBwYWlycyBhZGRyZXNzIC0gbGVuZ3RoOiBmaXJz\n" - "dCBmb3IgUExMIGNvbmZpZw0KPiArcmVnaXN0ZXJzIGFuZCBzZWNvbmQgZm9yIGNvcnJlc3BvbmRp\n" - "bmcgTE9DSyBDR1UgcmVnaXN0ZXIuDQo+ICstIGNsb2Nrczogc2hhbGwgYmUgdGhlIGlucHV0IHBh\n" - "cmVudCBjbG9jayBwaGFuZGxlIGZvciB0aGUgUExMLg0KPiArLSAjY2xvY2stY2VsbHM6IGZyb20g\n" - "Y29tbW9uIGNsb2NrIGJpbmRpbmc7IFNob3VsZCBhbHdheXMgYmUgc2V0IHRvIDAuDQo+ICsNCj4g\n" - "K0V4YW1wbGU6DQo+ICsJaW5wdXQtY2xrOiBpbnB1dC1jbGsgew0KPiArCQljbG9jay1mcmVxdWVu\n" - "Y3kgPSA8MzMzMzMzMzM+Ow0KPiArCQljb21wYXRpYmxlID0gImZpeGVkLWNsb2NrIjsNCj4gKwkJ\n" - "I2Nsb2NrLWNlbGxzID0gPDA+Ow0KPiArCX07DQo+ICsNCj4gKwljb3JlLWNsazogY29yZS1jbGtA\n" - "ODAgew0KPiArCQljb21wYXRpYmxlID0gInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2siOw0KPiAr\n" - "CQlyZWcgPSA8MHg4MCAweDEwIDB4MTAwIDB4MTA+Ow0KPiArCQkjY2xvY2stY2VsbHMgPSA8MD47\n" - "DQo+ICsJCWNsb2NrcyA9IDwmaW5wdXQtY2xrPjsNCj4gKwl9Ow0KPiBkaWZmIC0tZ2l0IGEvTUFJ\n" - "TlRBSU5FUlMgYi9NQUlOVEFJTkVSUw0KPiBpbmRleCAzOTYwZTdmLi41ODA1ODMzIDEwMDY0NA0K\n" - "PiAtLS0gYS9NQUlOVEFJTkVSUw0KPiArKysgYi9NQUlOVEFJTkVSUw0KPiBAQCAtMTE5MTAsNiAr\n" - "MTE5MTAsMTIgQEAgRjoJYXJjaC9hcmMvcGxhdC1heHMxMHgNCj4gwqBGOglhcmNoL2FyYy9ib290\n" - "L2R0cy9heCoNCj4gwqBGOglEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvYXJjL2F4\n" - "czEwKg0KPiDCoA0KPiArU1lOT1BTWVMgQVJDIFNEUCBjbG9jayBkcml2ZXINCj4gK006CVZsYWQg\n" - "WmFraGFyb3YgPHZ6YWtoYXJAc3lub3BzeXMuY29tPg0KPiArUzoJU3VwcG9ydGVkDQo+ICtGOglk\n" - "cml2ZXJzL2Nsay9heHMxMHgvKg0KPiArRjoJRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRp\n" - "bmdzL2Nsb2NrL3NucHMscGxsLWNsb2NrLnR4dA0KPiArDQo+IMKgU1lTVEVNIENPTkZJR1VSQVRJ\n" - "T04gKFNZU0NPTikNCj4gwqBNOglMZWUgSm9uZXMgPGxlZS5qb25lc0BsaW5hcm8ub3JnPg0KPiDC\n" - "oE06CUFybmQgQmVyZ21hbm4gPGFybmRAYXJuZGIuZGU+DQo+IGRpZmYgLS1naXQgYS9kcml2ZXJz\n" - "L2Nsay9heHMxMHgvTWFrZWZpbGUgYi9kcml2ZXJzL2Nsay9heHMxMHgvTWFrZWZpbGUNCj4gaW5k\n" - "ZXggMDE5OTZiOC4uZDc0N2RlYSAxMDA2NDQNCj4gLS0tIGEvZHJpdmVycy9jbGsvYXhzMTB4L01h\n" - "a2VmaWxlDQo+ICsrKyBiL2RyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZQ0KPiBAQCAtMSArMSwy\n" - "IEBADQo+IMKgb2JqLXkgKz0gaTJzX3BsbF9jbG9jay5vDQo+ICtvYmoteSArPSBwbGxfY2xvY2su\n" - "bw0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jIGIvZHJpdmVy\n" - "cy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+IGluZGV4\n" - "IDAwMDAwMDAuLjc4NGEwYTINCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJzL2Nsay9h\n" - "eHMxMHgvcGxsX2Nsb2NrLmMNCj4gQEAgLTAsMCArMSwzODQgQEANCj4gKy8qDQo+ICsgKiBTeW5v\n" - "cHN5cyBBWFMxMFggU0RQIEdlbmVyaWMgUExMIGNsb2NrIGRyaXZlcg0KPiArICoNCj4gKyAqIENv\n" - "cHlyaWdodCAoQykgMjAxNyBTeW5vcHN5cw0KPiArICoNCj4gKyAqIFRoaXMgZmlsZSBpcyBsaWNl\n" - "bnNlZCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYw0KPiArICogTGlj\n" - "ZW5zZSB2ZXJzaW9uIDIuIFRoaXMgcHJvZ3JhbSBpcyBsaWNlbnNlZCAiYXMgaXMiIHdpdGhvdXQg\n" - "YW55DQo+ICsgKiB3YXJyYW50eSBvZiBhbnkga2luZCwgd2hldGhlciBleHByZXNzIG9yIGltcGxp\n" - "ZWQuDQo+ICsgKi8NCj4gKw0KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPg0K\n" - "PiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92\n" - "aWRlci5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+DQo+ICsjaW5jbHVkZSA8bGludXgv\n" - "ZXJyLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ICsjaW5jbHVkZSA8bGludXgv\n" - "b2ZfYWRkcmVzcy5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPg0KPiArI2luY2x1\n" - "ZGUgPGxpbnV4L3NsYWIuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPg0KPiArDQo+ICsvKiBQ\n" - "TEwgcmVnaXN0ZXJzIGFkZHJlc3NlcyAqLw0KPiArI2RlZmluZSBQTExfUkVHX0lESVYJMHgwDQo+\n" - "ICsjZGVmaW5lIFBMTF9SRUdfRkJESVYJMHg0DQo+ICsjZGVmaW5lIFBMTF9SRUdfT0RJVgkweDgN\n" - "Cj4gKw0KPiArLyoNCj4gKyAqIEJpdCBmaWVsZHMgb2YgdGhlIFBMTCBJRElWL0ZCRElWL09ESVYg\n" - "cmVnaXN0ZXJzOg0KPiArICrCoMKgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f\n" - "X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQo+ICsgKiB8MzHCoMKgwqDCoMKg\n" - "wqDCoMKgwqDCoMKgwqDCoMKgwqDCoDE1fMKgwqDCoMKgMTTCoMKgwqDCoHzCoMKgwqAxM8KgwqDC\n" - "oHzCoMKgMTLCoMKgfDExwqDCoMKgwqDCoMKgwqDCoMKgNnw1wqDCoMKgwqDCoMKgwqDCoMKgMHwN\n" - "Cj4gKyAqIHwtLS0tLS0tUkVTUlZFRC0tLS0tLXwtTk9VUERBVEUtfC1CWVBBU1MtfC1FREdFLXwt\n" - "LUhJR0hUSU1FLS18LS1MT1dUSU1FLS18DQo+ICsgKiB8X19fX19fX19fX19fX19fX19fX198X19f\n" - "X19fX19fX3xfX19fX19fX3xfX19fX198X19fX19fX19fX19ffF9fX19fX19fX19ffA0KPiArICoN\n" - "Cj4gKyAqIEZvbGxvd2luZyBtYWNyb3MgZGV0aXJtaW5lIHRoZSB3YXkgb2YgYWNjZXNzIHRvIHRo\n" - "ZXNlIHJlZ2lzdGVycw0KPiArICogVGhleSBzaG91bGQgYmUgc2V0IHVwIG9ubHkgdXNpbmcgdGhl\n" - "IG1hY3Jvcy4NCj4gKyAqIHJlZyBzaG91bGQgYmUgYW5kIHVpbnQzMl90IHZhcmlhYmxlLg0KPiAr\n" - "ICovDQo+ICsNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTE9XKHJlZykJCQlcDQo+ICsJKCgocmVn\n" - "KSAmICgweDNGIDw8IDApKSA+PiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9ISUdIKHJlZykJ\n" - "CQlcDQo+ICsJKCgocmVnKSAmICgweDNGIDw8IDYpKSA+PiA2KQ0KPiArI2RlZmluZSBQTExfUkVH\n" - "X0dFVF9FREdFKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQoMTIpKSkgPyAxIDogMCkNCj4g\n" - "KyNkZWZpbmUgUExMX1JFR19HRVRfQllQQVNTKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQo\n" - "MTMpKSkgPyAxIDogMCkNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTk9VUEQocmVnKQkJCVwNCj4g\n" - "KwkoKChyZWcpICYgKEJJVCgxNCkpKSA/IDEgOiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9Q\n" - "QUQocmVnKQkJCVwNCj4gKwkoKChyZWcpICYgKDB4MUZGRkYgPDwgMTUpKSA+PiAxNSkNCj4gKw0K\n" - "PiArI2RlZmluZSBQTExfUkVHX1NFVF9MT1cocmVnLCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAo\n" - "KCh2YWx1ZSkgJiAweDNGKSA8PCAwKTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9ISUdIKHJl\n" - "ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDNGKSA8PCA2KTsgfQ0KPiAr\n" - "I2RlZmluZSBQTExfUkVHX1NFVF9FREdFKHJlZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2\n" - "YWx1ZSkgJiAweDAxKSA8PCAxMik7IH0NCj4gKyNkZWZpbmUgUExMX1JFR19TRVRfQllQQVNTKHJl\n" - "ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDAxKSA8PCAxMyk7IH0NCj4g\n" - "KyNkZWZpbmUgUExMX1JFR19TRVRfTk9VUEQocmVnLCB2YWx1ZSkJXA0KPiArCXsgcmVnIHw9ICgo\n" - "KHZhbHVlKSAmIDB4MDEpIDw8IDE0KTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9QQUQocmVn\n" - "LCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDFGRkZGKSA8PCAxNSk7IH0N\n" - "Cj4gKw0KPiArI2RlZmluZSBQTExfTE9DSwkweDENCj4gKyNkZWZpbmUgUExMX01BWF9MT0NLX1RJ\n" - "TUUgMTAwIC8qIDEwMCB1cyAqLw0KPiArDQo+ICtzdHJ1Y3QgcGxsX2NmZyB7DQo+ICsJdTMyIHJh\n" - "dGU7DQo+ICsJdTMyIGlkaXY7DQo+ICsJdTMyIGZiZGl2Ow0KPiArCXUzMiBvZGl2Ow0KPiArfTsN\n" - "Cj4gKw0KPiArc3RydWN0IHBsbF9vZl90YWJsZSB7DQo+ICsJdW5zaWduZWQgbG9uZyBwcmF0ZTsN\n" - "Cj4gKwlzdHJ1Y3QgcGxsX2NmZyAqcGxsX2NmZ190YWJsZTsNCj4gK307DQo+ICsNCj4gK3N0cnVj\n" - "dCBwbGxfb2ZfZGF0YSB7DQo+ICsJc3RydWN0IHBsbF9vZl90YWJsZSAqcGxsX3RhYmxlOw0KPiAr\n" - "fTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2ZfZGF0YSBwZ3VfcGxsX2RhdGEgPSB7DQo+\n" - "ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3RhYmxlIFtdKXsNCj4gKwkJew0KPiArCQkJ\n" - "LnByYXRlID0gMjcwMDAwMDAsDQo+ICsJCQkucGxsX2NmZ190YWJsZSA9IChzdHJ1Y3QgcGxsX2Nm\n" - "ZyBbXSl7DQo+ICsJCQkJeyAyNTIwMDAwMCwgMSwgODQsIDkwIH0sDQo+ICsJCQkJeyA1MDAwMDAw\n" - "MCwgMSwgMTAwLCA1NCB9LA0KPiArCQkJCXsgNzQyNTAwMDAsIDEsIDQ0LCAxNiB9LA0KPiArCQkJ\n" - "CXsgfSwNCj4gKwkJCX0sDQo+ICsJCX0sDQo+ICsJCS8qIFVzZWQgYXMgbGlzdCBsaW1pdGVyICov\n" - "DQo+ICsJCXsgfSwNCj4gKwl9LA0KPiArfTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2Zf\n" - "ZGF0YSBhcmNfcGxsX2RhdGEgPSB7DQo+ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3Rh\n" - "YmxlIFtdKXsNCj4gKwkJew0KPiArCQkJLnByYXRlID0gMzMzMzMzMzMsDQo+ICsJCQkucGxsX2Nm\n" - "Z190YWJsZSA9IChzdHJ1Y3QgcGxsX2NmZyBbXSl7DQo+ICsJCQkJeyAzMzMzMzMzMyzCoMKgMSwg\n" - "MSzCoMKgMSB9LA0KPiArCQkJCXsgNTAwMDAwMDAswqDCoDEsIDMwLCAyMCB9LA0KPiArCQkJCXsg\n" - "NzUwMDAwMDAswqDCoDIsIDQ1LCAxMCB9LA0KPiArCQkJCXsgOTAwMDAwMDAswqDCoDIsIDU0LCAx\n" - "MCB9LA0KPiArCQkJCXsgMTAwMDAwMDAwLCAxLCAzMCwgMTAgfSwNCj4gKwkJCQl7IDEyNTAwMDAw\n" - "MCwgMiwgNDUsIDYgfSwNCj4gKwkJCQl7IH0sDQo+ICsJCQl9LA0KPiArCQl9LA0KPiArCQkvKiBV\n" - "c2VkIGFzIGxpc3QgbGltaXRlciAqLw0KPiArCQl7IH0sDQo+ICsJfSwNCj4gK307DQo+ICsNCj4g\n" - "K3N0cnVjdCBwbGxfY2xrIHsNCj4gKwl2b2lkIF9faW9tZW0gKmJhc2U7DQo+ICsJdm9pZCBfX2lv\n" - "bWVtICpsb2NrOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfb2ZfZGF0YSAqcGxsX2RhdGE7DQo+ICsJ\n" - "c3RydWN0IGNsa19odyBodzsNCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7DQo+ICt9Ow0KPiArDQo+\n" - "ICtzdGF0aWMgaW5saW5lIHZvaWQgcGxsX3dyaXRlKHN0cnVjdCBwbGxfY2xrICpjbGssIHVuc2ln\n" - "bmVkIGludCByZWcsDQo+ICsJCXVuc2lnbmVkIGludCB2YWwpDQo+ICt7DQo+ICsJaW93cml0ZTMy\n" - "KHZhbCwgY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiArc3RhdGljIGlubGluZSB1MzIg\n" - "cGxsX3JlYWQoc3RydWN0IHBsbF9jbGsgKmNsaywNCj4gKwkJdW5zaWduZWQgaW50IHJlZykNCj4g\n" - "K3sNCj4gKwlyZXR1cm4gaW9yZWFkMzIoY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiAr\n" - "c3RhdGljIGlubGluZSBzdHJ1Y3QgcGxsX2NsayAqdG9fcGxsX2NsayhzdHJ1Y3QgY2xrX2h3ICpo\n" - "dykNCj4gK3sNCj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGh3LCBzdHJ1Y3QgcGxsX2NsaywgaHcp\n" - "Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBkaXZfZ2V0X3ZhbHVlKHVuc2lnbmVk\n" - "IGludCByZWcpDQo+ICt7DQo+ICsJaWYgKFBMTF9SRUdfR0VUX0JZUEFTUyhyZWcpKQ0KPiArCQly\n" - "ZXR1cm4gMTsNCj4gKw0KPiArCXJldHVybiAoUExMX1JFR19HRVRfSElHSChyZWcpICsgUExMX1JF\n" - "R19HRVRfTE9XKHJlZykpOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBlbmNvZGVf\n" - "ZGl2KHVuc2lnbmVkIGludCBpZCwgaW50IHVwZCkNCj4gK3sNCj4gKwl1aW50MzJfdCBkaXYgPSAw\n" - "Ow0KPiArDQo+ICsJUExMX1JFR19TRVRfTE9XKGRpdiwgKGlkJTIgPT0gMCkgPyBpZCA+PiAxIDog\n" - "KGlkID4+IDEpICsgMSk7DQo+ICsJUExMX1JFR19TRVRfSElHSChkaXYsIGlkID4+IDEpOw0KPiAr\n" - "CVBMTF9SRUdfU0VUX0VER0UoZGl2LCBpZCUyKTsNCj4gKwlQTExfUkVHX1NFVF9CWVBBU1MoZGl2\n" - "LCBpZCA9PSAxID8gMSA6IDApOw0KPiArCVBMTF9SRUdfU0VUX05PVVBEKGRpdiwgIXVwZCk7DQo+\n" - "ICsNCj4gKwlyZXR1cm4gZGl2Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHBs\n" - "bF9jZmcgKnBsbF9nZXRfY2ZnKHVuc2lnbmVkIGxvbmcgcHJhdGUsDQo+ICsJCWNvbnN0IHN0cnVj\n" - "dCBwbGxfb2ZfdGFibGUgKnBsbF90YWJsZSkNCj4gK3sNCj4gKwlpbnQgaTsNCj4gKw0KPiArCWZv\n" - "ciAoaSA9IDA7IHBsbF90YWJsZVtpXS5wcmF0ZSAhPSAwOyBpKyspDQo+ICsJCWlmIChwbGxfdGFi\n" - "bGVbaV0ucHJhdGUgPT0gcHJhdGUpDQo+ICsJCQlyZXR1cm4gcGxsX3RhYmxlW2ldLnBsbF9jZmdf\n" - "dGFibGU7DQo+ICsNCj4gKwlyZXR1cm4gTlVMTDsNCj4gK30NCj4gKw0KPiArc3RhdGljIHVuc2ln\n" - "bmVkIGxvbmcgcGxsX3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LA0KPiArCQkJdW5zaWdu\n" - "ZWQgbG9uZyBwYXJlbnRfcmF0ZSkNCj4gK3sNCj4gKwl1NjQgcmF0ZTsNCj4gKwl1MzIgaWRpdiwg\n" - "ZmJkaXYsIG9kaXY7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcpOw0K\n" - "PiArDQo+ICsJaWRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0lESVYp\n" - "KTsNCj4gKwlmYmRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0ZCRElW\n" - "KSk7DQo+ICsJb2RpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX09ESVYp\n" - "KTsNCj4gKw0KPiArCXJhdGUgPSAodTY0KXBhcmVudF9yYXRlICogZmJkaXY7DQo+ICsJZG9fZGl2\n" - "KHJhdGUsIGlkaXYgKiBvZGl2KTsNCj4gKw0KPiArCXJldHVybiAodW5zaWduZWQgbG9uZylyYXRl\n" - "Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgbG9uZyBwbGxfcm91bmRfcmF0ZShzdHJ1Y3QgY2xrX2h3\n" - "ICpodywgdW5zaWduZWQgbG9uZyByYXRlLA0KPiArCQkJdW5zaWduZWQgbG9uZyAqcHJhdGUpDQo+\n" - "ICt7DQo+ICsJaW50IGk7DQo+ICsJbG9uZyBiZXN0X3JhdGU7DQo+ICsJc3RydWN0IHBsbF9jbGsg\n" - "KmNsayA9IHRvX3BsbF9jbGsoaHcpOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2Zn\n" - "ID0gcGxsX2dldF9jZmcoKnByYXRlLA0KPiArCQkJY2xrLT5wbGxfZGF0YS0+cGxsX3RhYmxlKTsN\n" - "Cj4gKw0KPiArCWlmICghcGxsX2NmZykgew0KPiArCQlkZXZfZXJyKGNsay0+ZGV2LCAiaW52YWxp\n" - "ZCBwYXJlbnQgcmF0ZT0lbGRcbiIsICpwcmF0ZSk7DQo+ICsJCXJldHVybiAtRUlOVkFMOw0KPiAr\n" - "CX0NCj4gKw0KPiArCWlmIChwbGxfY2ZnWzBdLnJhdGUgPT0gMCkNCj4gKwkJcmV0dXJuIC1FSU5W\n" - "QUw7DQo+ICsNCj4gKwliZXN0X3JhdGUgPSBwbGxfY2ZnWzBdLnJhdGU7DQo+ICsNCj4gKwlmb3Ig\n" - "KGkgPSAxOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChhYnMocmF0ZSAt\n" - "IHBsbF9jZmdbaV0ucmF0ZSkgPCBhYnMocmF0ZSAtIGJlc3RfcmF0ZSkpDQo+ICsJCQliZXN0X3Jh\n" - "dGUgPSBwbGxfY2ZnW2ldLnJhdGU7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIGJlc3RfcmF0ZTsN\n" - "Cj4gK30NCj4gKw0KPiArc3RhdGljIGludCBwbGxfc2V0X3JhdGUoc3RydWN0IGNsa19odyAqaHcs\n" - "IHVuc2lnbmVkIGxvbmcgcmF0ZSwNCj4gKwkJCXVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpDQo+\n" - "ICt7DQo+ICsJaW50IGk7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcp\n" - "Ow0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2ZnID0gcGxsX2dldF9jZmcocGFyZW50\n" - "X3JhdGUsDQo+ICsJCQljbGstPnBsbF9kYXRhLT5wbGxfdGFibGUpOw0KPiArDQo+ICsJaWYgKCFw\n" - "bGxfY2ZnKSB7DQo+ICsJCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHBhcmVudCByYXRlPSVs\n" - "ZFxuIiwgcGFyZW50X3JhdGUpOw0KPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gKwl9DQo+ICsNCj4g\n" - "Kwlmb3IgKGkgPSAwOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChwbGxf\n" - "Y2ZnW2ldLnJhdGUgPT0gcmF0ZSkgew0KPiArCQkJcGxsX3dyaXRlKGNsaywgUExMX1JFR19JRElW\n" - "LA0KPiArCQkJCQllbmNvZGVfZGl2KHBsbF9jZmdbaV0uaWRpdiwgMCkpOw0KPiArCQkJcGxsX3dy\n" - "aXRlKGNsaywgUExMX1JFR19GQkRJViwNCj4gKwkJCQkJZW5jb2RlX2RpdihwbGxfY2ZnW2ldLmZi\n" - "ZGl2LCAwKSk7DQo+ICsJCQlwbGxfd3JpdGUoY2xrLCBQTExfUkVHX09ESVYsDQo+ICsJCQkJCWVu\n" - "Y29kZV9kaXYocGxsX2NmZ1tpXS5vZGl2LCAxKSk7DQo+ICsNCj4gKwkJCS8qDQo+ICsJCQnCoCog\n" - "V2FpdCB1bnRpbCBDR1UgcmVsb2Nrcy4NCj4gKwkJCcKgKiBJZiBhZnRlciB0aW1lb3V0IENHVSBp\n" - "cyB1bmxvY2tlZCB5ZXQgcmV0dXJuIGVycm9yDQo+ICsJCQnCoCovDQo+ICsJCQl1ZGVsYXkoUExM\n" - "X01BWF9MT0NLX1RJTUUpOw0KPiArCQkJaWYgKGlvcmVhZDMyKGNsay0+bG9jaykgJiBQTExfTE9D\n" - "SykNCj4gKwkJCQlyZXR1cm4gMDsNCj4gKwkJCWVsc2UNCj4gKwkJCQlyZXR1cm4gLUVUSU1FRE9V\n" - "VDsNCj4gKwkJfQ0KPiArCX0NCj4gKw0KPiArCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHJh\n" - "dGU9JWxkLCBwYXJlbnRfcmF0ZT0lbGRcbiIsIHJhdGUsDQo+ICsJCQlwYXJlbnRfcmF0ZSk7DQo+\n" - "ICsJcmV0dXJuIC1FSU5WQUw7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY2xr\n" - "X29wcyBwbGxfb3BzID0gew0KPiArCS5yZWNhbGNfcmF0ZSA9IHBsbF9yZWNhbGNfcmF0ZSwNCj4g\n" - "Kwkucm91bmRfcmF0ZSA9IHBsbF9yb3VuZF9yYXRlLA0KPiArCS5zZXRfcmF0ZSA9IHBsbF9zZXRf\n" - "cmF0ZSwNCj4gK307DQo+ICsNCj4gK3N0YXRpYyBpbnQgcGxsX2Nsa19wcm9iZShzdHJ1Y3QgcGxh\n" - "dGZvcm1fZGV2aWNlICpwZGV2KQ0KPiArew0KPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2\n" - "LT5kZXY7DQo+ICsJY29uc3QgY2hhciAqcGFyZW50X25hbWU7DQo+ICsJc3RydWN0IGNsayAqY2xr\n" - "Ow0KPiArCXN0cnVjdCBwbGxfY2xrICpwbGxfY2xrOw0KPiArCXN0cnVjdCByZXNvdXJjZSAqbWVt\n" - "Ow0KPiArCXN0cnVjdCBjbGtfaW5pdF9kYXRhIGluaXQgPSB7IH07DQo+ICsNCj4gKwlwbGxfY2xr\n" - "ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJ\n" - "aWYgKCFwbGxfY2xrKQ0KPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gKw0KPiArCW1lbSA9IHBsYXRm\n" - "b3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7DQo+ICsJcGxsX2Nsay0+\n" - "YmFzZSA9IGRldm1faW9yZW1hcF9yZXNvdXJjZShkZXYsIG1lbSk7DQo+ICsJaWYgKElTX0VSUihw\n" - "bGxfY2xrLT5iYXNlKSkNCj4gKwkJcmV0dXJuIFBUUl9FUlIocGxsX2Nsay0+YmFzZSk7DQo+ICsN\n" - "Cj4gKwltZW0gPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDEp\n" - "Ow0KPiArCXBsbF9jbGstPmxvY2sgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCBtZW0pOw0K\n" - "PiArCWlmIChJU19FUlIocGxsX2Nsay0+bG9jaykpDQo+ICsJCXJldHVybiBQVFJfRVJSKHBsbF9j\n" - "bGstPmJhc2UpOw0KPiArDQo+ICsJaW5pdC5uYW1lID0gZGV2LT5vZl9ub2RlLT5uYW1lOw0KPiAr\n" - "CWluaXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVu\n" - "dF9uYW1lKGRldi0+b2Zfbm9kZSwgMCk7DQo+ICsJaW5pdC5wYXJlbnRfbmFtZXMgPSAmcGFyZW50\n" - "X25hbWU7DQo+ICsJaW5pdC5udW1fcGFyZW50cyA9IDE7DQo+ICsJcGxsX2Nsay0+aHcuaW5pdCA9\n" - "ICZpbml0Ow0KPiArCXBsbF9jbGstPmRldiA9IGRldjsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9\n" - "IG9mX2RldmljZV9nZXRfbWF0Y2hfZGF0YShkZXYpOw0KPiArDQo+ICsJaWYgKCFwbGxfY2xrLT5w\n" - "bGxfZGF0YSkgew0KPiArCQlkZXZfZXJyKGRldiwgIk5vIE9GIG1hdGNoIGRhdGEgcHJvdmlkZWRc\n" - "biIpOw0KPiArCQkJcmV0dXJuIC1FSU5WQUw7DQo+ICsJfQ0KPiArDQo+ICsJY2xrID0gZGV2bV9j\n" - "bGtfcmVnaXN0ZXIoZGV2LCAmcGxsX2Nsay0+aHcpOw0KPiArCWlmIChJU19FUlIoY2xrKSkgew0K\n" - "PiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byByZWdpc3RlciAlcyBjbG9jayAoJWxkKVxuIiwN\n" - "Cj4gKwkJCQlpbml0Lm5hbWUsIFBUUl9FUlIoY2xrKSk7DQo+ICsJCXJldHVybiBQVFJfRVJSKGNs\n" - "ayk7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIG9mX2Nsa19hZGRfcHJvdmlkZXIoZGV2LT5vZl9u\n" - "b2RlLCBvZl9jbGtfc3JjX3NpbXBsZV9nZXQsIGNsayk7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBp\n" - "bnQgcGxsX2Nsa19yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gK3sNCj4g\n" - "KwlvZl9jbGtfZGVsX3Byb3ZpZGVyKHBkZXYtPmRldi5vZl9ub2RlKTsNCj4gKwlyZXR1cm4gMDsN\n" - "Cj4gK30NCj4gKw0KPiArc3RhdGljIHZvaWQgX19pbml0IG9mX3BsbF9jbGtfc2V0dXAoc3RydWN0\n" - "IGRldmljZV9ub2RlICpub2RlKQ0KPiArew0KPiArCWNvbnN0IGNoYXIgKnBhcmVudF9uYW1lOw0K\n" - "PiArCXN0cnVjdCBjbGsgKmNsazsNCj4gKwlzdHJ1Y3QgcGxsX2NsayAqcGxsX2NsazsNCj4gKwlz\n" - "dHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0ID0geyB9Ow0KPiArDQo+ICsJcGxsX2NsayA9IGt6YWxs\n" - "b2Moc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJaWYgKCFwbGxfY2xrKQ0KPiAr\n" - "CQlyZXR1cm47DQo+ICsNCj4gKwlwbGxfY2xrLT5iYXNlID0gb2ZfaW9tYXAobm9kZSwgMCk7DQo+\n" - "ICsJaWYgKCFwbGxfY2xrLT5iYXNlKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBwbGwg\n" - "ZGl2IHJlZ2lzdGVyc1xuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+YmFzZSk7DQo+ICsJCXJl\n" - "dHVybjsNCj4gKwl9DQo+ICsNCj4gKwlwbGxfY2xrLT5sb2NrID0gb2ZfaW9tYXAobm9kZSwgMSk7\n" - "DQo+ICsJaWYgKCFwbGxfY2xrLT5sb2NrKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBw\n" - "bGwgbG9jayByZWdpc3RlclxuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+bG9jayk7DQo+ICsJ\n" - "CXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlpbml0Lm5hbWUgPSBub2RlLT5uYW1lOw0KPiArCWlu\n" - "aXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVudF9u\n" - "YW1lKG5vZGUsIDApOw0KPiArCWluaXQucGFyZW50X25hbWVzID0gJnBhcmVudF9uYW1lOw0KPiAr\n" - "CWluaXQubnVtX3BhcmVudHMgPSBwYXJlbnRfbmFtZSA/IDEgOiAwOw0KPiArCXBsbF9jbGstPmh3\n" - "LmluaXQgPSAmaW5pdDsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9ICZhcmNfcGxsX2RhdGE7DQo+\n" - "ICsNCj4gKwljbGsgPSBjbGtfcmVnaXN0ZXIoTlVMTCwgJnBsbF9jbGstPmh3KTsNCj4gKwlpZiAo\n" - "SVNfRVJSKGNsaykpIHsNCj4gKwkJcHJfZXJyKCJmYWlsZWQgdG8gcmVnaXN0ZXIgJXMgY2xvY2sg\n" - "KCVsZClcbiIsDQo+ICsJCQkJbm9kZS0+bmFtZSwgUFRSX0VSUihjbGspKTsNCj4gKwkJa2ZyZWUo\n" - "cGxsX2Nsayk7DQo+ICsJCXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlvZl9jbGtfYWRkX3Byb3Zp\n" - "ZGVyKG5vZGUsIG9mX2Nsa19zcmNfc2ltcGxlX2dldCwgY2xrKTsNCj4gK30NCj4gKw0KPiArQ0xL\n" - "X09GX0RFQ0xBUkUoYXhzMTB4X3BsbF9jbG9jaywgInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2si\n" - "LCBvZl9wbGxfY2xrX3NldHVwKTsNCj4gKw0KPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp\n" - "Y2VfaWQgcGxsX2Nsa19pZFtdID0gew0KPiArCXsgLmNvbXBhdGlibGUgPSAic25wcyxheHMxMHgt\n" - "YXJjLXBsbC1jbG9jayIsIC5kYXRhID0gJmFyY19wbGxfZGF0YX0sDQo+ICsJeyAuY29tcGF0aWJs\n" - "ZSA9ICJzbnBzLGF4czEweC1wZ3UtcGxsLWNsb2NrIiwgLmRhdGEgPSAmcGd1X3BsbF9kYXRhfSwN\n" - "Cj4gKwl7IH0sDQo+ICt9Ow0KPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgcGxsX2Nsa19pZCk7\n" - "DQo+ICsNCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIHBsbF9jbGtfZHJpdmVyID0g\n" - "ew0KPiArCS5kcml2ZXIgPSB7DQo+ICsJCS5uYW1lID0gImF4czEweC1wbGwtY2xvY2siLA0KPiAr\n" - "CQkub2ZfbWF0Y2hfdGFibGUgPSBwbGxfY2xrX2lkLA0KPiArCX0sDQo+ICsJLnByb2JlID0gcGxs\n" - "X2Nsa19wcm9iZSwNCj4gKwkucmVtb3ZlID0gcGxsX2Nsa19yZW1vdmUsDQo+ICt9Ow0KPiArYnVp\n" - "bHRpbl9wbGF0Zm9ybV9kcml2ZXIocGxsX2Nsa19kcml2ZXIpOw0KPiArDQo+ICtNT0RVTEVfQVVU\n" - "SE9SKCJWbGFkIFpha2hhcm92IDx2emFraGFyQHN5bm9wc3lzLmNvbT4iKTsNCj4gK01PRFVMRV9E\n" - "RVNDUklQVElPTigiU3lub3BzeXMgQVhTMTBYIFNEUCBHZW5lcmljIFBMTCBDbG9jayBEcml2ZXIi\n" - "KTsNCj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsNCg0KTWF5YmUgeW91IGhhdmUgYW55IGNv\n" - "bW1lbnRzIG9yIHJlbWFya3MgYWJvdXQgdGhpcyBwYXRjaD8gQW5kIGlmIHlvdSBkb24ndCBjb3Vs\n" - "ZCB5b3UgcGxlYXNlIGFwcGx5IGl0Lg0KDQpUaGFua3MhDQoNCi0tIA0KQmVzdCByZWdhcmRzLA0K\n" - VmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+ + "Hi Michael, Stephen,\n" + "\n" + "On Tue, 2017-02-21 at 16:11 +0300, Vlad Zakharov wrote:\n" + "> AXS10X boards manages it's clocks using various PLLs. These PLL has same\n" + "> dividers and corresponding control registers mapped to different addresses.\n" + "> So we add one common driver for such PLLs.\n" + "> \n" + "> Each PLL on AXS10X board consist of three dividers: IDIV, FBDIV and\n" + "> ODIV. Output clock value is managed using these dividers.\n" + "> \n" + "> We add pre-defined tables with supported rate values and appropriate\n" + "> configurations of IDIV, FBDIV and ODIV for each value.\n" + "> \n" + "> As of today we add support for PLLs that generate clock for the\n" + "> following devices:\n" + "> \303\202\302\240* ARC core on AXC CPU tiles.\n" + "> \303\202\302\240* ARC PGU on ARC SDP Mainboard.\n" + "> and more to come later.\n" + "> \n" + "> Acked-by: Rob Herring <robh@kernel.org>\n" + "> Signed-off-by: Vlad Zakharov <vzakhar@synopsys.com>\n" + "> Signed-off-by: Jose Abreu <joabreu@synopsys.com>\n" + "> Cc: Michael Turquette <mturquette@baylibre.com>\n" + "> Cc: Stephen Boyd <sboyd@codeaurora.org>\n" + "> Cc: Mark Rutland <mark.rutland@arm.com>\n" + "> ---\n" + "> Cc: Rob Herring <robh@kernel.org>\n" + "> Changes v1..v2\n" + "> \303\202\302\240- Replace '_' with '-' in device tree nodes\n" + "> \n" + "> \303\202\302\240.../devicetree/bindings/clock/snps,pll-clock.txt\303\202\302\240\303\202\302\240\303\202\302\240|\303\202\302\240\303\202\302\24028 ++\n" + "> \303\202\302\240MAINTAINERS\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240|\303\202\302\240\303\202\302\240\303\202\302\2406 +\n" + "> \303\202\302\240drivers/clk/axs10x/Makefile\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240|\303\202\302\240\303\202\302\240\303\202\302\2401 +\n" + "> \303\202\302\240drivers/clk/axs10x/pll_clock.c\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240| 384 +++++++++++++++++++++\n" + "> \303\202\302\2404 files changed, 419 insertions(+)\n" + "> \303\202\302\240create mode 100644 Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> \303\202\302\240create mode 100644 drivers/clk/axs10x/pll_clock.c\n" + "> \n" + "> diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> new file mode 100644\n" + "> index 0000000..5706246\n" + "> --- /dev/null\n" + "> +++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> @@ -0,0 +1,28 @@\n" + "> +Binding for the AXS10X Generic PLL clock\n" + "> +\n" + "> +This binding uses the common clock binding[1].\n" + "> +\n" + "> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt\n" + "> +\n" + "> +Required properties:\n" + "> +- compatible: should be \"snps,axs10x-<name>-pll-clock\"\n" + "> +\303\202\302\240\303\202\302\240\"snps,axs10x-arc-pll-clock\"\n" + "> +\303\202\302\240\303\202\302\240\"snps,axs10x-pgu-pll-clock\"\n" + "> +- reg: should always contain 2 pairs address - length: first for PLL config\n" + "> +registers and second for corresponding LOCK CGU register.\n" + "> +- clocks: shall be the input parent clock phandle for the PLL.\n" + "> +- #clock-cells: from common clock binding; Should always be set to 0.\n" + "> +\n" + "> +Example:\n" + "> +\tinput-clk: input-clk {\n" + "> +\t\tclock-frequency = <33333333>;\n" + "> +\t\tcompatible = \"fixed-clock\";\n" + "> +\t\t#clock-cells = <0>;\n" + "> +\t};\n" + "> +\n" + "> +\tcore-clk: core-clk@80 {\n" + "> +\t\tcompatible = \"snps,axs10x-arc-pll-clock\";\n" + "> +\t\treg = <0x80 0x10 0x100 0x10>;\n" + "> +\t\t#clock-cells = <0>;\n" + "> +\t\tclocks = <&input-clk>;\n" + "> +\t};\n" + "> diff --git a/MAINTAINERS b/MAINTAINERS\n" + "> index 3960e7f..5805833 100644\n" + "> --- a/MAINTAINERS\n" + "> +++ b/MAINTAINERS\n" + "> @@ -11910,6 +11910,12 @@ F:\tarch/arc/plat-axs10x\n" + "> \303\202\302\240F:\tarch/arc/boot/dts/ax*\n" + "> \303\202\302\240F:\tDocumentation/devicetree/bindings/arc/axs10*\n" + "> \303\202\302\240\n" + "> +SYNOPSYS ARC SDP clock driver\n" + "> +M:\tVlad Zakharov <vzakhar@synopsys.com>\n" + "> +S:\tSupported\n" + "> +F:\tdrivers/clk/axs10x/*\n" + "> +F:\tDocumentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> +\n" + "> \303\202\302\240SYSTEM CONFIGURATION (SYSCON)\n" + "> \303\202\302\240M:\tLee Jones <lee.jones@linaro.org>\n" + "> \303\202\302\240M:\tArnd Bergmann <arnd@arndb.de>\n" + "> diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile\n" + "> index 01996b8..d747dea 100644\n" + "> --- a/drivers/clk/axs10x/Makefile\n" + "> +++ b/drivers/clk/axs10x/Makefile\n" + "> @@ -1 +1,2 @@\n" + "> \303\202\302\240obj-y += i2s_pll_clock.o\n" + "> +obj-y += pll_clock.o\n" + "> diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c\n" + "> new file mode 100644\n" + "> index 0000000..784a0a2\n" + "> --- /dev/null\n" + "> +++ b/drivers/clk/axs10x/pll_clock.c\n" + "> @@ -0,0 +1,384 @@\n" + "> +/*\n" + "> + * Synopsys AXS10X SDP Generic PLL clock driver\n" + "> + *\n" + "> + * Copyright (C) 2017 Synopsys\n" + "> + *\n" + "> + * This file is licensed under the terms of the GNU General Public\n" + "> + * License version 2. This program is licensed \"as is\" without any\n" + "> + * warranty of any kind, whether express or implied.\n" + "> + */\n" + "> +\n" + "> +#include <linux/platform_device.h>\n" + "> +#include <linux/module.h>\n" + "> +#include <linux/clk-provider.h>\n" + "> +#include <linux/delay.h>\n" + "> +#include <linux/err.h>\n" + "> +#include <linux/device.h>\n" + "> +#include <linux/of_address.h>\n" + "> +#include <linux/of_device.h>\n" + "> +#include <linux/slab.h>\n" + "> +#include <linux/of.h>\n" + "> +\n" + "> +/* PLL registers addresses */\n" + "> +#define PLL_REG_IDIV\t0x0\n" + "> +#define PLL_REG_FBDIV\t0x4\n" + "> +#define PLL_REG_ODIV\t0x8\n" + "> +\n" + "> +/*\n" + "> + * Bit fields of the PLL IDIV/FBDIV/ODIV registers:\n" + "> + *\303\202\302\240\303\202\302\240________________________________________________________________________\n" + "> + * |31\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\24015|\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\24014\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240|\303\202\302\240\303\202\302\240\303\202\302\24013\303\202\302\240\303\202\302\240\303\202\302\240|\303\202\302\240\303\202\302\24012\303\202\302\240\303\202\302\240|11\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\2406|5\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\240\303\202\302\2400|\n" + "> + * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--|\n" + "> + * |____________________|__________|________|______|____________|___________|\n" + "> + *\n" + "> + * Following macros detirmine the way of access to these registers\n" + "> + * They should be set up only using the macros.\n" + "> + * reg should be and uint32_t variable.\n" + "> + */\n" + "> +\n" + "> +#define PLL_REG_GET_LOW(reg)\t\t\t\\\n" + "> +\t(((reg) & (0x3F << 0)) >> 0)\n" + "> +#define PLL_REG_GET_HIGH(reg)\t\t\t\\\n" + "> +\t(((reg) & (0x3F << 6)) >> 6)\n" + "> +#define PLL_REG_GET_EDGE(reg)\t\t\t\\\n" + "> +\t(((reg) & (BIT(12))) ? 1 : 0)\n" + "> +#define PLL_REG_GET_BYPASS(reg)\t\t\t\\\n" + "> +\t(((reg) & (BIT(13))) ? 1 : 0)\n" + "> +#define PLL_REG_GET_NOUPD(reg)\t\t\t\\\n" + "> +\t(((reg) & (BIT(14))) ? 1 : 0)\n" + "> +#define PLL_REG_GET_PAD(reg)\t\t\t\\\n" + "> +\t(((reg) & (0x1FFFF << 15)) >> 15)\n" + "> +\n" + "> +#define PLL_REG_SET_LOW(reg, value)\t\t\\\n" + "> +\t{ reg |= (((value) & 0x3F) << 0); }\n" + "> +#define PLL_REG_SET_HIGH(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x3F) << 6); }\n" + "> +#define PLL_REG_SET_EDGE(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x01) << 12); }\n" + "> +#define PLL_REG_SET_BYPASS(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x01) << 13); }\n" + "> +#define PLL_REG_SET_NOUPD(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x01) << 14); }\n" + "> +#define PLL_REG_SET_PAD(reg, value)\t\t\\\n" + "> +\t{ reg |= (((value) & 0x1FFFF) << 15); }\n" + "> +\n" + "> +#define PLL_LOCK\t0x1\n" + "> +#define PLL_MAX_LOCK_TIME 100 /* 100 us */\n" + "> +\n" + "> +struct pll_cfg {\n" + "> +\tu32 rate;\n" + "> +\tu32 idiv;\n" + "> +\tu32 fbdiv;\n" + "> +\tu32 odiv;\n" + "> +};\n" + "> +\n" + "> +struct pll_of_table {\n" + "> +\tunsigned long prate;\n" + "> +\tstruct pll_cfg *pll_cfg_table;\n" + "> +};\n" + "> +\n" + "> +struct pll_of_data {\n" + "> +\tstruct pll_of_table *pll_table;\n" + "> +};\n" + "> +\n" + "> +static struct pll_of_data pgu_pll_data = {\n" + "> +\t.pll_table = (struct pll_of_table []){\n" + "> +\t\t{\n" + "> +\t\t\t.prate = 27000000,\n" + "> +\t\t\t.pll_cfg_table = (struct pll_cfg []){\n" + "> +\t\t\t\t{ 25200000, 1, 84, 90 },\n" + "> +\t\t\t\t{ 50000000, 1, 100, 54 },\n" + "> +\t\t\t\t{ 74250000, 1, 44, 16 },\n" + "> +\t\t\t\t{ },\n" + "> +\t\t\t},\n" + "> +\t\t},\n" + "> +\t\t/* Used as list limiter */\n" + "> +\t\t{ },\n" + "> +\t},\n" + "> +};\n" + "> +\n" + "> +static struct pll_of_data arc_pll_data = {\n" + "> +\t.pll_table = (struct pll_of_table []){\n" + "> +\t\t{\n" + "> +\t\t\t.prate = 33333333,\n" + "> +\t\t\t.pll_cfg_table = (struct pll_cfg []){\n" + "> +\t\t\t\t{ 33333333,\303\202\302\240\303\202\302\2401, 1,\303\202\302\240\303\202\302\2401 },\n" + "> +\t\t\t\t{ 50000000,\303\202\302\240\303\202\302\2401, 30, 20 },\n" + "> +\t\t\t\t{ 75000000,\303\202\302\240\303\202\302\2402, 45, 10 },\n" + "> +\t\t\t\t{ 90000000,\303\202\302\240\303\202\302\2402, 54, 10 },\n" + "> +\t\t\t\t{ 100000000, 1, 30, 10 },\n" + "> +\t\t\t\t{ 125000000, 2, 45, 6 },\n" + "> +\t\t\t\t{ },\n" + "> +\t\t\t},\n" + "> +\t\t},\n" + "> +\t\t/* Used as list limiter */\n" + "> +\t\t{ },\n" + "> +\t},\n" + "> +};\n" + "> +\n" + "> +struct pll_clk {\n" + "> +\tvoid __iomem *base;\n" + "> +\tvoid __iomem *lock;\n" + "> +\tconst struct pll_of_data *pll_data;\n" + "> +\tstruct clk_hw hw;\n" + "> +\tstruct device *dev;\n" + "> +};\n" + "> +\n" + "> +static inline void pll_write(struct pll_clk *clk, unsigned int reg,\n" + "> +\t\tunsigned int val)\n" + "> +{\n" + "> +\tiowrite32(val, clk->base + reg);\n" + "> +}\n" + "> +\n" + "> +static inline u32 pll_read(struct pll_clk *clk,\n" + "> +\t\tunsigned int reg)\n" + "> +{\n" + "> +\treturn ioread32(clk->base + reg);\n" + "> +}\n" + "> +\n" + "> +static inline struct pll_clk *to_pll_clk(struct clk_hw *hw)\n" + "> +{\n" + "> +\treturn container_of(hw, struct pll_clk, hw);\n" + "> +}\n" + "> +\n" + "> +static inline u32 div_get_value(unsigned int reg)\n" + "> +{\n" + "> +\tif (PLL_REG_GET_BYPASS(reg))\n" + "> +\t\treturn 1;\n" + "> +\n" + "> +\treturn (PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg));\n" + "> +}\n" + "> +\n" + "> +static inline u32 encode_div(unsigned int id, int upd)\n" + "> +{\n" + "> +\tuint32_t div = 0;\n" + "> +\n" + "> +\tPLL_REG_SET_LOW(div, (id%2 == 0) ? id >> 1 : (id >> 1) + 1);\n" + "> +\tPLL_REG_SET_HIGH(div, id >> 1);\n" + "> +\tPLL_REG_SET_EDGE(div, id%2);\n" + "> +\tPLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0);\n" + "> +\tPLL_REG_SET_NOUPD(div, !upd);\n" + "> +\n" + "> +\treturn div;\n" + "> +}\n" + "> +\n" + "> +static const struct pll_cfg *pll_get_cfg(unsigned long prate,\n" + "> +\t\tconst struct pll_of_table *pll_table)\n" + "> +{\n" + "> +\tint i;\n" + "> +\n" + "> +\tfor (i = 0; pll_table[i].prate != 0; i++)\n" + "> +\t\tif (pll_table[i].prate == prate)\n" + "> +\t\t\treturn pll_table[i].pll_cfg_table;\n" + "> +\n" + "> +\treturn NULL;\n" + "> +}\n" + "> +\n" + "> +static unsigned long pll_recalc_rate(struct clk_hw *hw,\n" + "> +\t\t\tunsigned long parent_rate)\n" + "> +{\n" + "> +\tu64 rate;\n" + "> +\tu32 idiv, fbdiv, odiv;\n" + "> +\tstruct pll_clk *clk = to_pll_clk(hw);\n" + "> +\n" + "> +\tidiv = div_get_value(pll_read(clk, PLL_REG_IDIV));\n" + "> +\tfbdiv = div_get_value(pll_read(clk, PLL_REG_FBDIV));\n" + "> +\todiv = div_get_value(pll_read(clk, PLL_REG_ODIV));\n" + "> +\n" + "> +\trate = (u64)parent_rate * fbdiv;\n" + "> +\tdo_div(rate, idiv * odiv);\n" + "> +\n" + "> +\treturn (unsigned long)rate;\n" + "> +}\n" + "> +\n" + "> +static long pll_round_rate(struct clk_hw *hw, unsigned long rate,\n" + "> +\t\t\tunsigned long *prate)\n" + "> +{\n" + "> +\tint i;\n" + "> +\tlong best_rate;\n" + "> +\tstruct pll_clk *clk = to_pll_clk(hw);\n" + "> +\tconst struct pll_cfg *pll_cfg = pll_get_cfg(*prate,\n" + "> +\t\t\tclk->pll_data->pll_table);\n" + "> +\n" + "> +\tif (!pll_cfg) {\n" + "> +\t\tdev_err(clk->dev, \"invalid parent rate=%ld\\n\", *prate);\n" + "> +\t\treturn -EINVAL;\n" + "> +\t}\n" + "> +\n" + "> +\tif (pll_cfg[0].rate == 0)\n" + "> +\t\treturn -EINVAL;\n" + "> +\n" + "> +\tbest_rate = pll_cfg[0].rate;\n" + "> +\n" + "> +\tfor (i = 1; pll_cfg[i].rate != 0; i++) {\n" + "> +\t\tif (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate))\n" + "> +\t\t\tbest_rate = pll_cfg[i].rate;\n" + "> +\t}\n" + "> +\n" + "> +\treturn best_rate;\n" + "> +}\n" + "> +\n" + "> +static int pll_set_rate(struct clk_hw *hw, unsigned long rate,\n" + "> +\t\t\tunsigned long parent_rate)\n" + "> +{\n" + "> +\tint i;\n" + "> +\tstruct pll_clk *clk = to_pll_clk(hw);\n" + "> +\tconst struct pll_cfg *pll_cfg = pll_get_cfg(parent_rate,\n" + "> +\t\t\tclk->pll_data->pll_table);\n" + "> +\n" + "> +\tif (!pll_cfg) {\n" + "> +\t\tdev_err(clk->dev, \"invalid parent rate=%ld\\n\", parent_rate);\n" + "> +\t\treturn -EINVAL;\n" + "> +\t}\n" + "> +\n" + "> +\tfor (i = 0; pll_cfg[i].rate != 0; i++) {\n" + "> +\t\tif (pll_cfg[i].rate == rate) {\n" + "> +\t\t\tpll_write(clk, PLL_REG_IDIV,\n" + "> +\t\t\t\t\tencode_div(pll_cfg[i].idiv, 0));\n" + "> +\t\t\tpll_write(clk, PLL_REG_FBDIV,\n" + "> +\t\t\t\t\tencode_div(pll_cfg[i].fbdiv, 0));\n" + "> +\t\t\tpll_write(clk, PLL_REG_ODIV,\n" + "> +\t\t\t\t\tencode_div(pll_cfg[i].odiv, 1));\n" + "> +\n" + "> +\t\t\t/*\n" + "> +\t\t\t\303\202\302\240* Wait until CGU relocks.\n" + "> +\t\t\t\303\202\302\240* If after timeout CGU is unlocked yet return error\n" + "> +\t\t\t\303\202\302\240*/\n" + "> +\t\t\tudelay(PLL_MAX_LOCK_TIME);\n" + "> +\t\t\tif (ioread32(clk->lock) & PLL_LOCK)\n" + "> +\t\t\t\treturn 0;\n" + "> +\t\t\telse\n" + "> +\t\t\t\treturn -ETIMEDOUT;\n" + "> +\t\t}\n" + "> +\t}\n" + "> +\n" + "> +\tdev_err(clk->dev, \"invalid rate=%ld, parent_rate=%ld\\n\", rate,\n" + "> +\t\t\tparent_rate);\n" + "> +\treturn -EINVAL;\n" + "> +}\n" + "> +\n" + "> +static const struct clk_ops pll_ops = {\n" + "> +\t.recalc_rate = pll_recalc_rate,\n" + "> +\t.round_rate = pll_round_rate,\n" + "> +\t.set_rate = pll_set_rate,\n" + "> +};\n" + "> +\n" + "> +static int pll_clk_probe(struct platform_device *pdev)\n" + "> +{\n" + "> +\tstruct device *dev = &pdev->dev;\n" + "> +\tconst char *parent_name;\n" + "> +\tstruct clk *clk;\n" + "> +\tstruct pll_clk *pll_clk;\n" + "> +\tstruct resource *mem;\n" + "> +\tstruct clk_init_data init = { };\n" + "> +\n" + "> +\tpll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);\n" + "> +\tif (!pll_clk)\n" + "> +\t\treturn -ENOMEM;\n" + "> +\n" + "> +\tmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n" + "> +\tpll_clk->base = devm_ioremap_resource(dev, mem);\n" + "> +\tif (IS_ERR(pll_clk->base))\n" + "> +\t\treturn PTR_ERR(pll_clk->base);\n" + "> +\n" + "> +\tmem = platform_get_resource(pdev, IORESOURCE_MEM, 1);\n" + "> +\tpll_clk->lock = devm_ioremap_resource(dev, mem);\n" + "> +\tif (IS_ERR(pll_clk->lock))\n" + "> +\t\treturn PTR_ERR(pll_clk->base);\n" + "> +\n" + "> +\tinit.name = dev->of_node->name;\n" + "> +\tinit.ops = &pll_ops;\n" + "> +\tparent_name = of_clk_get_parent_name(dev->of_node, 0);\n" + "> +\tinit.parent_names = &parent_name;\n" + "> +\tinit.num_parents = 1;\n" + "> +\tpll_clk->hw.init = &init;\n" + "> +\tpll_clk->dev = dev;\n" + "> +\tpll_clk->pll_data = of_device_get_match_data(dev);\n" + "> +\n" + "> +\tif (!pll_clk->pll_data) {\n" + "> +\t\tdev_err(dev, \"No OF match data provided\\n\");\n" + "> +\t\t\treturn -EINVAL;\n" + "> +\t}\n" + "> +\n" + "> +\tclk = devm_clk_register(dev, &pll_clk->hw);\n" + "> +\tif (IS_ERR(clk)) {\n" + "> +\t\tdev_err(dev, \"failed to register %s clock (%ld)\\n\",\n" + "> +\t\t\t\tinit.name, PTR_ERR(clk));\n" + "> +\t\treturn PTR_ERR(clk);\n" + "> +\t}\n" + "> +\n" + "> +\treturn of_clk_add_provider(dev->of_node, of_clk_src_simple_get, clk);\n" + "> +}\n" + "> +\n" + "> +static int pll_clk_remove(struct platform_device *pdev)\n" + "> +{\n" + "> +\tof_clk_del_provider(pdev->dev.of_node);\n" + "> +\treturn 0;\n" + "> +}\n" + "> +\n" + "> +static void __init of_pll_clk_setup(struct device_node *node)\n" + "> +{\n" + "> +\tconst char *parent_name;\n" + "> +\tstruct clk *clk;\n" + "> +\tstruct pll_clk *pll_clk;\n" + "> +\tstruct clk_init_data init = { };\n" + "> +\n" + "> +\tpll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);\n" + "> +\tif (!pll_clk)\n" + "> +\t\treturn;\n" + "> +\n" + "> +\tpll_clk->base = of_iomap(node, 0);\n" + "> +\tif (!pll_clk->base) {\n" + "> +\t\tpr_err(\"failed to map pll div registers\\n\");\n" + "> +\t\tiounmap(pll_clk->base);\n" + "> +\t\treturn;\n" + "> +\t}\n" + "> +\n" + "> +\tpll_clk->lock = of_iomap(node, 1);\n" + "> +\tif (!pll_clk->lock) {\n" + "> +\t\tpr_err(\"failed to map pll lock register\\n\");\n" + "> +\t\tiounmap(pll_clk->lock);\n" + "> +\t\treturn;\n" + "> +\t}\n" + "> +\n" + "> +\tinit.name = node->name;\n" + "> +\tinit.ops = &pll_ops;\n" + "> +\tparent_name = of_clk_get_parent_name(node, 0);\n" + "> +\tinit.parent_names = &parent_name;\n" + "> +\tinit.num_parents = parent_name ? 1 : 0;\n" + "> +\tpll_clk->hw.init = &init;\n" + "> +\tpll_clk->pll_data = &arc_pll_data;\n" + "> +\n" + "> +\tclk = clk_register(NULL, &pll_clk->hw);\n" + "> +\tif (IS_ERR(clk)) {\n" + "> +\t\tpr_err(\"failed to register %s clock (%ld)\\n\",\n" + "> +\t\t\t\tnode->name, PTR_ERR(clk));\n" + "> +\t\tkfree(pll_clk);\n" + "> +\t\treturn;\n" + "> +\t}\n" + "> +\n" + "> +\tof_clk_add_provider(node, of_clk_src_simple_get, clk);\n" + "> +}\n" + "> +\n" + "> +CLK_OF_DECLARE(axs10x_pll_clock, \"snps,axs10x-arc-pll-clock\", of_pll_clk_setup);\n" + "> +\n" + "> +static const struct of_device_id pll_clk_id[] = {\n" + "> +\t{ .compatible = \"snps,axs10x-arc-pll-clock\", .data = &arc_pll_data},\n" + "> +\t{ .compatible = \"snps,axs10x-pgu-pll-clock\", .data = &pgu_pll_data},\n" + "> +\t{ },\n" + "> +};\n" + "> +MODULE_DEVICE_TABLE(of, pll_clk_id);\n" + "> +\n" + "> +static struct platform_driver pll_clk_driver = {\n" + "> +\t.driver = {\n" + "> +\t\t.name = \"axs10x-pll-clock\",\n" + "> +\t\t.of_match_table = pll_clk_id,\n" + "> +\t},\n" + "> +\t.probe = pll_clk_probe,\n" + "> +\t.remove = pll_clk_remove,\n" + "> +};\n" + "> +builtin_platform_driver(pll_clk_driver);\n" + "> +\n" + "> +MODULE_AUTHOR(\"Vlad Zakharov <vzakhar@synopsys.com>\");\n" + "> +MODULE_DESCRIPTION(\"Synopsys AXS10X SDP Generic PLL Clock Driver\");\n" + "> +MODULE_LICENSE(\"GPL v2\");\n" + "\n" + "Maybe you have any comments or remarks about this patch? And if you don't could you please apply it.\n" + "\n" + "Thanks!\n" + "\n" + "-- \n" + "Best regards,\n" + "Vlad Zakharov <vzakhar@synopsys.com>N\302\213\302\247\302\262\303\246\303\254r\302\270\302\233y\303\272\303\250\302\232\303\230b\302\262X\302\254\302\266\303\207\302\247v\303\230^\302\226)\303\236\302\272{.n\303\207+\302\211\302\267\302\235z\303\270\302\234z\303\232\303\236z)\303\255\302\205\303\246\303\250w*\037jg\302\254\302\261\302\250\036\302\266\302\211\302\232\302\216\302\212\303\235\302\242j.\303\257\303\233\302\260\\\302\275\302\275M\302\216\303\272gj\303\214\303\246a\303\227\002\302\233\302\233\302\226' \302\231\302\251\303\236\302\242\302\270\f\302\242\302\267\302\246j:+v\302\211\302\250\302\212w\303\250j\303\230m\302\266\302\237\303\277\302\276\a\302\253\302\221\303\252\303\247zZ+\302\203\303\271\302\232\302\216\302\212\303\235\302\242j\"\302\235\303\272!\302\266i" -36fae7fa84d07b8086c925e623f6ba88940d662237db2b05d1e273fbce8d0b15 +f303a5060d506215ea0700896d2f1792b09e1eb12ffd534b39d230047a4d777a
diff --git a/a/1.txt b/N3/1.txt index 1a5bc4f..0c12fa6 100644 --- a/a/1.txt +++ b/N3/1.txt @@ -1,265 +1,495 @@ -SGkgTWljaGFlbCwgU3RlcGhlbiwNCg0KT24gVHVlLCAyMDE3LTAyLTIxIGF0IDE2OjExICswMzAw -LCBWbGFkIFpha2hhcm92IHdyb3RlOg0KPiBBWFMxMFggYm9hcmRzIG1hbmFnZXMgaXQncyBjbG9j -a3MgdXNpbmcgdmFyaW91cyBQTExzLiBUaGVzZSBQTEwgaGFzIHNhbWUNCj4gZGl2aWRlcnMgYW5k -IGNvcnJlc3BvbmRpbmcgY29udHJvbCByZWdpc3RlcnMgbWFwcGVkIHRvIGRpZmZlcmVudCBhZGRy -ZXNzZXMuDQo+IFNvIHdlIGFkZCBvbmUgY29tbW9uIGRyaXZlciBmb3Igc3VjaCBQTExzLg0KPiAN -Cj4gRWFjaCBQTEwgb24gQVhTMTBYIGJvYXJkIGNvbnNpc3Qgb2YgdGhyZWUgZGl2aWRlcnM6IElE -SVYsIEZCRElWIGFuZA0KPiBPRElWLiBPdXRwdXQgY2xvY2sgdmFsdWUgaXMgbWFuYWdlZCB1c2lu -ZyB0aGVzZSBkaXZpZGVycy4NCj4gDQo+IFdlIGFkZCBwcmUtZGVmaW5lZCB0YWJsZXMgd2l0aCBz -dXBwb3J0ZWQgcmF0ZSB2YWx1ZXMgYW5kIGFwcHJvcHJpYXRlDQo+IGNvbmZpZ3VyYXRpb25zIG9m -IElESVYsIEZCRElWIGFuZCBPRElWIGZvciBlYWNoIHZhbHVlLg0KPiANCj4gQXMgb2YgdG9kYXkg -d2UgYWRkIHN1cHBvcnQgZm9yIFBMTHMgdGhhdCBnZW5lcmF0ZSBjbG9jayBmb3IgdGhlDQo+IGZv -bGxvd2luZyBkZXZpY2VzOg0KPiDCoCogQVJDIGNvcmUgb24gQVhDIENQVSB0aWxlcy4NCj4gwqAq -IEFSQyBQR1Ugb24gQVJDIFNEUCBNYWluYm9hcmQuDQo+IGFuZCBtb3JlIHRvIGNvbWUgbGF0ZXIu -DQo+IA0KPiBBY2tlZC1ieTogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gU2lnbmVk -LW9mZi1ieTogVmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+DQo+IFNpZ25lZC1v -ZmYtYnk6IEpvc2UgQWJyZXUgPGpvYWJyZXVAc3lub3BzeXMuY29tPg0KPiBDYzogTWljaGFlbCBU -dXJxdWV0dGUgPG10dXJxdWV0dGVAYmF5bGlicmUuY29tPg0KPiBDYzogU3RlcGhlbiBCb3lkIDxz -Ym95ZEBjb2RlYXVyb3JhLm9yZz4NCj4gQ2M6IE1hcmsgUnV0bGFuZCA8bWFyay5ydXRsYW5kQGFy -bS5jb20+DQo+IC0tLQ0KPiBDYzogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gQ2hh -bmdlcyB2MS4udjINCj4gwqAtIFJlcGxhY2UgJ18nIHdpdGggJy0nIGluIGRldmljZSB0cmVlIG5v -ZGVzDQo+IA0KPiDCoC4uLi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxsLWNsb2Nr -LnR4dMKgwqDCoHzCoMKgMjggKysNCj4gwqBNQUlOVEFJTkVSU8KgwqDCoMKgwqDCoMKgwqDCoMKg -wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC -oMKgfMKgwqDCoDYgKw0KPiDCoGRyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZcKgwqDCoMKgwqDC -oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAxICsNCj4gwqBkcml2 -ZXJzL2Nsay9heHMxMHgvcGxsX2Nsb2NrLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC -oMKgwqDCoMKgwqB8IDM4NCArKysrKysrKysrKysrKysrKysrKysNCj4gwqA0IGZpbGVzIGNoYW5n -ZWQsIDQxOSBpbnNlcnRpb25zKCspDQo+IMKgY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp -b24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gwqBjcmVh -dGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IA0KPiBkaWZm -IC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxs -LWNsb2NrLnR4dA0KPiBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9z -bnBzLHBsbC1jbG9jay50eHQNCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gaW5kZXggMDAwMDAw -MC4uNTcwNjI0Ng0KPiAtLS0gL2Rldi9udWxsDQo+ICsrKyBiL0RvY3VtZW50YXRpb24vZGV2aWNl -dHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gQEAgLTAsMCArMSwyOCBA -QA0KPiArQmluZGluZyBmb3IgdGhlIEFYUzEwWCBHZW5lcmljIFBMTCBjbG9jaw0KPiArDQo+ICtU -aGlzIGJpbmRpbmcgdXNlcyB0aGUgY29tbW9uIGNsb2NrIGJpbmRpbmdbMV0uDQo+ICsNCj4gK1sx -XSBEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvY2xvY2svY2xvY2stYmluZGluZ3Mu -dHh0DQo+ICsNCj4gK1JlcXVpcmVkIHByb3BlcnRpZXM6DQo+ICstIGNvbXBhdGlibGU6IHNob3Vs -ZCBiZSAic25wcyxheHMxMHgtPG5hbWU+LXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgt -YXJjLXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgtcGd1LXBsbC1jbG9jayINCj4gKy0g -cmVnOiBzaG91bGQgYWx3YXlzIGNvbnRhaW4gMiBwYWlycyBhZGRyZXNzIC0gbGVuZ3RoOiBmaXJz -dCBmb3IgUExMIGNvbmZpZw0KPiArcmVnaXN0ZXJzIGFuZCBzZWNvbmQgZm9yIGNvcnJlc3BvbmRp -bmcgTE9DSyBDR1UgcmVnaXN0ZXIuDQo+ICstIGNsb2Nrczogc2hhbGwgYmUgdGhlIGlucHV0IHBh -cmVudCBjbG9jayBwaGFuZGxlIGZvciB0aGUgUExMLg0KPiArLSAjY2xvY2stY2VsbHM6IGZyb20g -Y29tbW9uIGNsb2NrIGJpbmRpbmc7IFNob3VsZCBhbHdheXMgYmUgc2V0IHRvIDAuDQo+ICsNCj4g -K0V4YW1wbGU6DQo+ICsJaW5wdXQtY2xrOiBpbnB1dC1jbGsgew0KPiArCQljbG9jay1mcmVxdWVu -Y3kgPSA8MzMzMzMzMzM+Ow0KPiArCQljb21wYXRpYmxlID0gImZpeGVkLWNsb2NrIjsNCj4gKwkJ -I2Nsb2NrLWNlbGxzID0gPDA+Ow0KPiArCX07DQo+ICsNCj4gKwljb3JlLWNsazogY29yZS1jbGtA -ODAgew0KPiArCQljb21wYXRpYmxlID0gInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2siOw0KPiAr -CQlyZWcgPSA8MHg4MCAweDEwIDB4MTAwIDB4MTA+Ow0KPiArCQkjY2xvY2stY2VsbHMgPSA8MD47 -DQo+ICsJCWNsb2NrcyA9IDwmaW5wdXQtY2xrPjsNCj4gKwl9Ow0KPiBkaWZmIC0tZ2l0IGEvTUFJ -TlRBSU5FUlMgYi9NQUlOVEFJTkVSUw0KPiBpbmRleCAzOTYwZTdmLi41ODA1ODMzIDEwMDY0NA0K -PiAtLS0gYS9NQUlOVEFJTkVSUw0KPiArKysgYi9NQUlOVEFJTkVSUw0KPiBAQCAtMTE5MTAsNiAr -MTE5MTAsMTIgQEAgRjoJYXJjaC9hcmMvcGxhdC1heHMxMHgNCj4gwqBGOglhcmNoL2FyYy9ib290 -L2R0cy9heCoNCj4gwqBGOglEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvYXJjL2F4 -czEwKg0KPiDCoA0KPiArU1lOT1BTWVMgQVJDIFNEUCBjbG9jayBkcml2ZXINCj4gK006CVZsYWQg -WmFraGFyb3YgPHZ6YWtoYXJAc3lub3BzeXMuY29tPg0KPiArUzoJU3VwcG9ydGVkDQo+ICtGOglk -cml2ZXJzL2Nsay9heHMxMHgvKg0KPiArRjoJRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRp -bmdzL2Nsb2NrL3NucHMscGxsLWNsb2NrLnR4dA0KPiArDQo+IMKgU1lTVEVNIENPTkZJR1VSQVRJ -T04gKFNZU0NPTikNCj4gwqBNOglMZWUgSm9uZXMgPGxlZS5qb25lc0BsaW5hcm8ub3JnPg0KPiDC -oE06CUFybmQgQmVyZ21hbm4gPGFybmRAYXJuZGIuZGU+DQo+IGRpZmYgLS1naXQgYS9kcml2ZXJz -L2Nsay9heHMxMHgvTWFrZWZpbGUgYi9kcml2ZXJzL2Nsay9heHMxMHgvTWFrZWZpbGUNCj4gaW5k -ZXggMDE5OTZiOC4uZDc0N2RlYSAxMDA2NDQNCj4gLS0tIGEvZHJpdmVycy9jbGsvYXhzMTB4L01h -a2VmaWxlDQo+ICsrKyBiL2RyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZQ0KPiBAQCAtMSArMSwy -IEBADQo+IMKgb2JqLXkgKz0gaTJzX3BsbF9jbG9jay5vDQo+ICtvYmoteSArPSBwbGxfY2xvY2su -bw0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jIGIvZHJpdmVy -cy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+IGluZGV4 -IDAwMDAwMDAuLjc4NGEwYTINCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJzL2Nsay9h -eHMxMHgvcGxsX2Nsb2NrLmMNCj4gQEAgLTAsMCArMSwzODQgQEANCj4gKy8qDQo+ICsgKiBTeW5v -cHN5cyBBWFMxMFggU0RQIEdlbmVyaWMgUExMIGNsb2NrIGRyaXZlcg0KPiArICoNCj4gKyAqIENv -cHlyaWdodCAoQykgMjAxNyBTeW5vcHN5cw0KPiArICoNCj4gKyAqIFRoaXMgZmlsZSBpcyBsaWNl -bnNlZCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYw0KPiArICogTGlj -ZW5zZSB2ZXJzaW9uIDIuIFRoaXMgcHJvZ3JhbSBpcyBsaWNlbnNlZCAiYXMgaXMiIHdpdGhvdXQg -YW55DQo+ICsgKiB3YXJyYW50eSBvZiBhbnkga2luZCwgd2hldGhlciBleHByZXNzIG9yIGltcGxp -ZWQuDQo+ICsgKi8NCj4gKw0KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPg0K -PiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92 -aWRlci5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+DQo+ICsjaW5jbHVkZSA8bGludXgv -ZXJyLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ICsjaW5jbHVkZSA8bGludXgv -b2ZfYWRkcmVzcy5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPg0KPiArI2luY2x1 -ZGUgPGxpbnV4L3NsYWIuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPg0KPiArDQo+ICsvKiBQ -TEwgcmVnaXN0ZXJzIGFkZHJlc3NlcyAqLw0KPiArI2RlZmluZSBQTExfUkVHX0lESVYJMHgwDQo+ -ICsjZGVmaW5lIFBMTF9SRUdfRkJESVYJMHg0DQo+ICsjZGVmaW5lIFBMTF9SRUdfT0RJVgkweDgN -Cj4gKw0KPiArLyoNCj4gKyAqIEJpdCBmaWVsZHMgb2YgdGhlIFBMTCBJRElWL0ZCRElWL09ESVYg -cmVnaXN0ZXJzOg0KPiArICrCoMKgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f -X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQo+ICsgKiB8MzHCoMKgwqDCoMKg -wqDCoMKgwqDCoMKgwqDCoMKgwqDCoDE1fMKgwqDCoMKgMTTCoMKgwqDCoHzCoMKgwqAxM8KgwqDC -oHzCoMKgMTLCoMKgfDExwqDCoMKgwqDCoMKgwqDCoMKgNnw1wqDCoMKgwqDCoMKgwqDCoMKgMHwN -Cj4gKyAqIHwtLS0tLS0tUkVTUlZFRC0tLS0tLXwtTk9VUERBVEUtfC1CWVBBU1MtfC1FREdFLXwt -LUhJR0hUSU1FLS18LS1MT1dUSU1FLS18DQo+ICsgKiB8X19fX19fX19fX19fX19fX19fX198X19f -X19fX19fX3xfX19fX19fX3xfX19fX198X19fX19fX19fX19ffF9fX19fX19fX19ffA0KPiArICoN -Cj4gKyAqIEZvbGxvd2luZyBtYWNyb3MgZGV0aXJtaW5lIHRoZSB3YXkgb2YgYWNjZXNzIHRvIHRo -ZXNlIHJlZ2lzdGVycw0KPiArICogVGhleSBzaG91bGQgYmUgc2V0IHVwIG9ubHkgdXNpbmcgdGhl -IG1hY3Jvcy4NCj4gKyAqIHJlZyBzaG91bGQgYmUgYW5kIHVpbnQzMl90IHZhcmlhYmxlLg0KPiAr -ICovDQo+ICsNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTE9XKHJlZykJCQlcDQo+ICsJKCgocmVn -KSAmICgweDNGIDw8IDApKSA+PiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9ISUdIKHJlZykJ -CQlcDQo+ICsJKCgocmVnKSAmICgweDNGIDw8IDYpKSA+PiA2KQ0KPiArI2RlZmluZSBQTExfUkVH -X0dFVF9FREdFKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQoMTIpKSkgPyAxIDogMCkNCj4g -KyNkZWZpbmUgUExMX1JFR19HRVRfQllQQVNTKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQo -MTMpKSkgPyAxIDogMCkNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTk9VUEQocmVnKQkJCVwNCj4g -KwkoKChyZWcpICYgKEJJVCgxNCkpKSA/IDEgOiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9Q -QUQocmVnKQkJCVwNCj4gKwkoKChyZWcpICYgKDB4MUZGRkYgPDwgMTUpKSA+PiAxNSkNCj4gKw0K -PiArI2RlZmluZSBQTExfUkVHX1NFVF9MT1cocmVnLCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAo -KCh2YWx1ZSkgJiAweDNGKSA8PCAwKTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9ISUdIKHJl -ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDNGKSA8PCA2KTsgfQ0KPiAr -I2RlZmluZSBQTExfUkVHX1NFVF9FREdFKHJlZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2 -YWx1ZSkgJiAweDAxKSA8PCAxMik7IH0NCj4gKyNkZWZpbmUgUExMX1JFR19TRVRfQllQQVNTKHJl -ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDAxKSA8PCAxMyk7IH0NCj4g -KyNkZWZpbmUgUExMX1JFR19TRVRfTk9VUEQocmVnLCB2YWx1ZSkJXA0KPiArCXsgcmVnIHw9ICgo -KHZhbHVlKSAmIDB4MDEpIDw8IDE0KTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9QQUQocmVn -LCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDFGRkZGKSA8PCAxNSk7IH0N -Cj4gKw0KPiArI2RlZmluZSBQTExfTE9DSwkweDENCj4gKyNkZWZpbmUgUExMX01BWF9MT0NLX1RJ -TUUgMTAwIC8qIDEwMCB1cyAqLw0KPiArDQo+ICtzdHJ1Y3QgcGxsX2NmZyB7DQo+ICsJdTMyIHJh -dGU7DQo+ICsJdTMyIGlkaXY7DQo+ICsJdTMyIGZiZGl2Ow0KPiArCXUzMiBvZGl2Ow0KPiArfTsN -Cj4gKw0KPiArc3RydWN0IHBsbF9vZl90YWJsZSB7DQo+ICsJdW5zaWduZWQgbG9uZyBwcmF0ZTsN -Cj4gKwlzdHJ1Y3QgcGxsX2NmZyAqcGxsX2NmZ190YWJsZTsNCj4gK307DQo+ICsNCj4gK3N0cnVj -dCBwbGxfb2ZfZGF0YSB7DQo+ICsJc3RydWN0IHBsbF9vZl90YWJsZSAqcGxsX3RhYmxlOw0KPiAr -fTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2ZfZGF0YSBwZ3VfcGxsX2RhdGEgPSB7DQo+ -ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3RhYmxlIFtdKXsNCj4gKwkJew0KPiArCQkJ -LnByYXRlID0gMjcwMDAwMDAsDQo+ICsJCQkucGxsX2NmZ190YWJsZSA9IChzdHJ1Y3QgcGxsX2Nm -ZyBbXSl7DQo+ICsJCQkJeyAyNTIwMDAwMCwgMSwgODQsIDkwIH0sDQo+ICsJCQkJeyA1MDAwMDAw -MCwgMSwgMTAwLCA1NCB9LA0KPiArCQkJCXsgNzQyNTAwMDAsIDEsIDQ0LCAxNiB9LA0KPiArCQkJ -CXsgfSwNCj4gKwkJCX0sDQo+ICsJCX0sDQo+ICsJCS8qIFVzZWQgYXMgbGlzdCBsaW1pdGVyICov -DQo+ICsJCXsgfSwNCj4gKwl9LA0KPiArfTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2Zf -ZGF0YSBhcmNfcGxsX2RhdGEgPSB7DQo+ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3Rh -YmxlIFtdKXsNCj4gKwkJew0KPiArCQkJLnByYXRlID0gMzMzMzMzMzMsDQo+ICsJCQkucGxsX2Nm -Z190YWJsZSA9IChzdHJ1Y3QgcGxsX2NmZyBbXSl7DQo+ICsJCQkJeyAzMzMzMzMzMyzCoMKgMSwg -MSzCoMKgMSB9LA0KPiArCQkJCXsgNTAwMDAwMDAswqDCoDEsIDMwLCAyMCB9LA0KPiArCQkJCXsg -NzUwMDAwMDAswqDCoDIsIDQ1LCAxMCB9LA0KPiArCQkJCXsgOTAwMDAwMDAswqDCoDIsIDU0LCAx -MCB9LA0KPiArCQkJCXsgMTAwMDAwMDAwLCAxLCAzMCwgMTAgfSwNCj4gKwkJCQl7IDEyNTAwMDAw -MCwgMiwgNDUsIDYgfSwNCj4gKwkJCQl7IH0sDQo+ICsJCQl9LA0KPiArCQl9LA0KPiArCQkvKiBV -c2VkIGFzIGxpc3QgbGltaXRlciAqLw0KPiArCQl7IH0sDQo+ICsJfSwNCj4gK307DQo+ICsNCj4g -K3N0cnVjdCBwbGxfY2xrIHsNCj4gKwl2b2lkIF9faW9tZW0gKmJhc2U7DQo+ICsJdm9pZCBfX2lv -bWVtICpsb2NrOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfb2ZfZGF0YSAqcGxsX2RhdGE7DQo+ICsJ -c3RydWN0IGNsa19odyBodzsNCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7DQo+ICt9Ow0KPiArDQo+ -ICtzdGF0aWMgaW5saW5lIHZvaWQgcGxsX3dyaXRlKHN0cnVjdCBwbGxfY2xrICpjbGssIHVuc2ln -bmVkIGludCByZWcsDQo+ICsJCXVuc2lnbmVkIGludCB2YWwpDQo+ICt7DQo+ICsJaW93cml0ZTMy -KHZhbCwgY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiArc3RhdGljIGlubGluZSB1MzIg -cGxsX3JlYWQoc3RydWN0IHBsbF9jbGsgKmNsaywNCj4gKwkJdW5zaWduZWQgaW50IHJlZykNCj4g -K3sNCj4gKwlyZXR1cm4gaW9yZWFkMzIoY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiAr -c3RhdGljIGlubGluZSBzdHJ1Y3QgcGxsX2NsayAqdG9fcGxsX2NsayhzdHJ1Y3QgY2xrX2h3ICpo -dykNCj4gK3sNCj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGh3LCBzdHJ1Y3QgcGxsX2NsaywgaHcp -Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBkaXZfZ2V0X3ZhbHVlKHVuc2lnbmVk -IGludCByZWcpDQo+ICt7DQo+ICsJaWYgKFBMTF9SRUdfR0VUX0JZUEFTUyhyZWcpKQ0KPiArCQly -ZXR1cm4gMTsNCj4gKw0KPiArCXJldHVybiAoUExMX1JFR19HRVRfSElHSChyZWcpICsgUExMX1JF -R19HRVRfTE9XKHJlZykpOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBlbmNvZGVf -ZGl2KHVuc2lnbmVkIGludCBpZCwgaW50IHVwZCkNCj4gK3sNCj4gKwl1aW50MzJfdCBkaXYgPSAw -Ow0KPiArDQo+ICsJUExMX1JFR19TRVRfTE9XKGRpdiwgKGlkJTIgPT0gMCkgPyBpZCA+PiAxIDog -KGlkID4+IDEpICsgMSk7DQo+ICsJUExMX1JFR19TRVRfSElHSChkaXYsIGlkID4+IDEpOw0KPiAr -CVBMTF9SRUdfU0VUX0VER0UoZGl2LCBpZCUyKTsNCj4gKwlQTExfUkVHX1NFVF9CWVBBU1MoZGl2 -LCBpZCA9PSAxID8gMSA6IDApOw0KPiArCVBMTF9SRUdfU0VUX05PVVBEKGRpdiwgIXVwZCk7DQo+ -ICsNCj4gKwlyZXR1cm4gZGl2Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHBs -bF9jZmcgKnBsbF9nZXRfY2ZnKHVuc2lnbmVkIGxvbmcgcHJhdGUsDQo+ICsJCWNvbnN0IHN0cnVj -dCBwbGxfb2ZfdGFibGUgKnBsbF90YWJsZSkNCj4gK3sNCj4gKwlpbnQgaTsNCj4gKw0KPiArCWZv -ciAoaSA9IDA7IHBsbF90YWJsZVtpXS5wcmF0ZSAhPSAwOyBpKyspDQo+ICsJCWlmIChwbGxfdGFi -bGVbaV0ucHJhdGUgPT0gcHJhdGUpDQo+ICsJCQlyZXR1cm4gcGxsX3RhYmxlW2ldLnBsbF9jZmdf -dGFibGU7DQo+ICsNCj4gKwlyZXR1cm4gTlVMTDsNCj4gK30NCj4gKw0KPiArc3RhdGljIHVuc2ln -bmVkIGxvbmcgcGxsX3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LA0KPiArCQkJdW5zaWdu -ZWQgbG9uZyBwYXJlbnRfcmF0ZSkNCj4gK3sNCj4gKwl1NjQgcmF0ZTsNCj4gKwl1MzIgaWRpdiwg -ZmJkaXYsIG9kaXY7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcpOw0K -PiArDQo+ICsJaWRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0lESVYp -KTsNCj4gKwlmYmRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0ZCRElW -KSk7DQo+ICsJb2RpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX09ESVYp -KTsNCj4gKw0KPiArCXJhdGUgPSAodTY0KXBhcmVudF9yYXRlICogZmJkaXY7DQo+ICsJZG9fZGl2 -KHJhdGUsIGlkaXYgKiBvZGl2KTsNCj4gKw0KPiArCXJldHVybiAodW5zaWduZWQgbG9uZylyYXRl -Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgbG9uZyBwbGxfcm91bmRfcmF0ZShzdHJ1Y3QgY2xrX2h3 -ICpodywgdW5zaWduZWQgbG9uZyByYXRlLA0KPiArCQkJdW5zaWduZWQgbG9uZyAqcHJhdGUpDQo+ -ICt7DQo+ICsJaW50IGk7DQo+ICsJbG9uZyBiZXN0X3JhdGU7DQo+ICsJc3RydWN0IHBsbF9jbGsg -KmNsayA9IHRvX3BsbF9jbGsoaHcpOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2Zn -ID0gcGxsX2dldF9jZmcoKnByYXRlLA0KPiArCQkJY2xrLT5wbGxfZGF0YS0+cGxsX3RhYmxlKTsN -Cj4gKw0KPiArCWlmICghcGxsX2NmZykgew0KPiArCQlkZXZfZXJyKGNsay0+ZGV2LCAiaW52YWxp -ZCBwYXJlbnQgcmF0ZT0lbGRcbiIsICpwcmF0ZSk7DQo+ICsJCXJldHVybiAtRUlOVkFMOw0KPiAr -CX0NCj4gKw0KPiArCWlmIChwbGxfY2ZnWzBdLnJhdGUgPT0gMCkNCj4gKwkJcmV0dXJuIC1FSU5W -QUw7DQo+ICsNCj4gKwliZXN0X3JhdGUgPSBwbGxfY2ZnWzBdLnJhdGU7DQo+ICsNCj4gKwlmb3Ig -KGkgPSAxOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChhYnMocmF0ZSAt -IHBsbF9jZmdbaV0ucmF0ZSkgPCBhYnMocmF0ZSAtIGJlc3RfcmF0ZSkpDQo+ICsJCQliZXN0X3Jh -dGUgPSBwbGxfY2ZnW2ldLnJhdGU7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIGJlc3RfcmF0ZTsN -Cj4gK30NCj4gKw0KPiArc3RhdGljIGludCBwbGxfc2V0X3JhdGUoc3RydWN0IGNsa19odyAqaHcs -IHVuc2lnbmVkIGxvbmcgcmF0ZSwNCj4gKwkJCXVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpDQo+ -ICt7DQo+ICsJaW50IGk7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcp -Ow0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2ZnID0gcGxsX2dldF9jZmcocGFyZW50 -X3JhdGUsDQo+ICsJCQljbGstPnBsbF9kYXRhLT5wbGxfdGFibGUpOw0KPiArDQo+ICsJaWYgKCFw -bGxfY2ZnKSB7DQo+ICsJCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHBhcmVudCByYXRlPSVs -ZFxuIiwgcGFyZW50X3JhdGUpOw0KPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gKwl9DQo+ICsNCj4g -Kwlmb3IgKGkgPSAwOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChwbGxf -Y2ZnW2ldLnJhdGUgPT0gcmF0ZSkgew0KPiArCQkJcGxsX3dyaXRlKGNsaywgUExMX1JFR19JRElW -LA0KPiArCQkJCQllbmNvZGVfZGl2KHBsbF9jZmdbaV0uaWRpdiwgMCkpOw0KPiArCQkJcGxsX3dy -aXRlKGNsaywgUExMX1JFR19GQkRJViwNCj4gKwkJCQkJZW5jb2RlX2RpdihwbGxfY2ZnW2ldLmZi -ZGl2LCAwKSk7DQo+ICsJCQlwbGxfd3JpdGUoY2xrLCBQTExfUkVHX09ESVYsDQo+ICsJCQkJCWVu -Y29kZV9kaXYocGxsX2NmZ1tpXS5vZGl2LCAxKSk7DQo+ICsNCj4gKwkJCS8qDQo+ICsJCQnCoCog -V2FpdCB1bnRpbCBDR1UgcmVsb2Nrcy4NCj4gKwkJCcKgKiBJZiBhZnRlciB0aW1lb3V0IENHVSBp -cyB1bmxvY2tlZCB5ZXQgcmV0dXJuIGVycm9yDQo+ICsJCQnCoCovDQo+ICsJCQl1ZGVsYXkoUExM -X01BWF9MT0NLX1RJTUUpOw0KPiArCQkJaWYgKGlvcmVhZDMyKGNsay0+bG9jaykgJiBQTExfTE9D -SykNCj4gKwkJCQlyZXR1cm4gMDsNCj4gKwkJCWVsc2UNCj4gKwkJCQlyZXR1cm4gLUVUSU1FRE9V -VDsNCj4gKwkJfQ0KPiArCX0NCj4gKw0KPiArCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHJh -dGU9JWxkLCBwYXJlbnRfcmF0ZT0lbGRcbiIsIHJhdGUsDQo+ICsJCQlwYXJlbnRfcmF0ZSk7DQo+ -ICsJcmV0dXJuIC1FSU5WQUw7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY2xr -X29wcyBwbGxfb3BzID0gew0KPiArCS5yZWNhbGNfcmF0ZSA9IHBsbF9yZWNhbGNfcmF0ZSwNCj4g -Kwkucm91bmRfcmF0ZSA9IHBsbF9yb3VuZF9yYXRlLA0KPiArCS5zZXRfcmF0ZSA9IHBsbF9zZXRf -cmF0ZSwNCj4gK307DQo+ICsNCj4gK3N0YXRpYyBpbnQgcGxsX2Nsa19wcm9iZShzdHJ1Y3QgcGxh -dGZvcm1fZGV2aWNlICpwZGV2KQ0KPiArew0KPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2 -LT5kZXY7DQo+ICsJY29uc3QgY2hhciAqcGFyZW50X25hbWU7DQo+ICsJc3RydWN0IGNsayAqY2xr -Ow0KPiArCXN0cnVjdCBwbGxfY2xrICpwbGxfY2xrOw0KPiArCXN0cnVjdCByZXNvdXJjZSAqbWVt -Ow0KPiArCXN0cnVjdCBjbGtfaW5pdF9kYXRhIGluaXQgPSB7IH07DQo+ICsNCj4gKwlwbGxfY2xr -ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJ -aWYgKCFwbGxfY2xrKQ0KPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gKw0KPiArCW1lbSA9IHBsYXRm -b3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7DQo+ICsJcGxsX2Nsay0+ -YmFzZSA9IGRldm1faW9yZW1hcF9yZXNvdXJjZShkZXYsIG1lbSk7DQo+ICsJaWYgKElTX0VSUihw -bGxfY2xrLT5iYXNlKSkNCj4gKwkJcmV0dXJuIFBUUl9FUlIocGxsX2Nsay0+YmFzZSk7DQo+ICsN -Cj4gKwltZW0gPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDEp -Ow0KPiArCXBsbF9jbGstPmxvY2sgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCBtZW0pOw0K -PiArCWlmIChJU19FUlIocGxsX2Nsay0+bG9jaykpDQo+ICsJCXJldHVybiBQVFJfRVJSKHBsbF9j -bGstPmJhc2UpOw0KPiArDQo+ICsJaW5pdC5uYW1lID0gZGV2LT5vZl9ub2RlLT5uYW1lOw0KPiAr -CWluaXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVu -dF9uYW1lKGRldi0+b2Zfbm9kZSwgMCk7DQo+ICsJaW5pdC5wYXJlbnRfbmFtZXMgPSAmcGFyZW50 -X25hbWU7DQo+ICsJaW5pdC5udW1fcGFyZW50cyA9IDE7DQo+ICsJcGxsX2Nsay0+aHcuaW5pdCA9 -ICZpbml0Ow0KPiArCXBsbF9jbGstPmRldiA9IGRldjsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9 -IG9mX2RldmljZV9nZXRfbWF0Y2hfZGF0YShkZXYpOw0KPiArDQo+ICsJaWYgKCFwbGxfY2xrLT5w -bGxfZGF0YSkgew0KPiArCQlkZXZfZXJyKGRldiwgIk5vIE9GIG1hdGNoIGRhdGEgcHJvdmlkZWRc -biIpOw0KPiArCQkJcmV0dXJuIC1FSU5WQUw7DQo+ICsJfQ0KPiArDQo+ICsJY2xrID0gZGV2bV9j -bGtfcmVnaXN0ZXIoZGV2LCAmcGxsX2Nsay0+aHcpOw0KPiArCWlmIChJU19FUlIoY2xrKSkgew0K -PiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byByZWdpc3RlciAlcyBjbG9jayAoJWxkKVxuIiwN -Cj4gKwkJCQlpbml0Lm5hbWUsIFBUUl9FUlIoY2xrKSk7DQo+ICsJCXJldHVybiBQVFJfRVJSKGNs -ayk7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIG9mX2Nsa19hZGRfcHJvdmlkZXIoZGV2LT5vZl9u -b2RlLCBvZl9jbGtfc3JjX3NpbXBsZV9nZXQsIGNsayk7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBp -bnQgcGxsX2Nsa19yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gK3sNCj4g -KwlvZl9jbGtfZGVsX3Byb3ZpZGVyKHBkZXYtPmRldi5vZl9ub2RlKTsNCj4gKwlyZXR1cm4gMDsN -Cj4gK30NCj4gKw0KPiArc3RhdGljIHZvaWQgX19pbml0IG9mX3BsbF9jbGtfc2V0dXAoc3RydWN0 -IGRldmljZV9ub2RlICpub2RlKQ0KPiArew0KPiArCWNvbnN0IGNoYXIgKnBhcmVudF9uYW1lOw0K -PiArCXN0cnVjdCBjbGsgKmNsazsNCj4gKwlzdHJ1Y3QgcGxsX2NsayAqcGxsX2NsazsNCj4gKwlz -dHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0ID0geyB9Ow0KPiArDQo+ICsJcGxsX2NsayA9IGt6YWxs -b2Moc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJaWYgKCFwbGxfY2xrKQ0KPiAr -CQlyZXR1cm47DQo+ICsNCj4gKwlwbGxfY2xrLT5iYXNlID0gb2ZfaW9tYXAobm9kZSwgMCk7DQo+ -ICsJaWYgKCFwbGxfY2xrLT5iYXNlKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBwbGwg -ZGl2IHJlZ2lzdGVyc1xuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+YmFzZSk7DQo+ICsJCXJl -dHVybjsNCj4gKwl9DQo+ICsNCj4gKwlwbGxfY2xrLT5sb2NrID0gb2ZfaW9tYXAobm9kZSwgMSk7 -DQo+ICsJaWYgKCFwbGxfY2xrLT5sb2NrKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBw -bGwgbG9jayByZWdpc3RlclxuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+bG9jayk7DQo+ICsJ -CXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlpbml0Lm5hbWUgPSBub2RlLT5uYW1lOw0KPiArCWlu -aXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVudF9u -YW1lKG5vZGUsIDApOw0KPiArCWluaXQucGFyZW50X25hbWVzID0gJnBhcmVudF9uYW1lOw0KPiAr -CWluaXQubnVtX3BhcmVudHMgPSBwYXJlbnRfbmFtZSA/IDEgOiAwOw0KPiArCXBsbF9jbGstPmh3 -LmluaXQgPSAmaW5pdDsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9ICZhcmNfcGxsX2RhdGE7DQo+ -ICsNCj4gKwljbGsgPSBjbGtfcmVnaXN0ZXIoTlVMTCwgJnBsbF9jbGstPmh3KTsNCj4gKwlpZiAo -SVNfRVJSKGNsaykpIHsNCj4gKwkJcHJfZXJyKCJmYWlsZWQgdG8gcmVnaXN0ZXIgJXMgY2xvY2sg -KCVsZClcbiIsDQo+ICsJCQkJbm9kZS0+bmFtZSwgUFRSX0VSUihjbGspKTsNCj4gKwkJa2ZyZWUo -cGxsX2Nsayk7DQo+ICsJCXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlvZl9jbGtfYWRkX3Byb3Zp -ZGVyKG5vZGUsIG9mX2Nsa19zcmNfc2ltcGxlX2dldCwgY2xrKTsNCj4gK30NCj4gKw0KPiArQ0xL -X09GX0RFQ0xBUkUoYXhzMTB4X3BsbF9jbG9jaywgInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2si -LCBvZl9wbGxfY2xrX3NldHVwKTsNCj4gKw0KPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp -Y2VfaWQgcGxsX2Nsa19pZFtdID0gew0KPiArCXsgLmNvbXBhdGlibGUgPSAic25wcyxheHMxMHgt -YXJjLXBsbC1jbG9jayIsIC5kYXRhID0gJmFyY19wbGxfZGF0YX0sDQo+ICsJeyAuY29tcGF0aWJs -ZSA9ICJzbnBzLGF4czEweC1wZ3UtcGxsLWNsb2NrIiwgLmRhdGEgPSAmcGd1X3BsbF9kYXRhfSwN -Cj4gKwl7IH0sDQo+ICt9Ow0KPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgcGxsX2Nsa19pZCk7 -DQo+ICsNCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIHBsbF9jbGtfZHJpdmVyID0g -ew0KPiArCS5kcml2ZXIgPSB7DQo+ICsJCS5uYW1lID0gImF4czEweC1wbGwtY2xvY2siLA0KPiAr -CQkub2ZfbWF0Y2hfdGFibGUgPSBwbGxfY2xrX2lkLA0KPiArCX0sDQo+ICsJLnByb2JlID0gcGxs -X2Nsa19wcm9iZSwNCj4gKwkucmVtb3ZlID0gcGxsX2Nsa19yZW1vdmUsDQo+ICt9Ow0KPiArYnVp -bHRpbl9wbGF0Zm9ybV9kcml2ZXIocGxsX2Nsa19kcml2ZXIpOw0KPiArDQo+ICtNT0RVTEVfQVVU -SE9SKCJWbGFkIFpha2hhcm92IDx2emFraGFyQHN5bm9wc3lzLmNvbT4iKTsNCj4gK01PRFVMRV9E -RVNDUklQVElPTigiU3lub3BzeXMgQVhTMTBYIFNEUCBHZW5lcmljIFBMTCBDbG9jayBEcml2ZXIi -KTsNCj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsNCg0KTWF5YmUgeW91IGhhdmUgYW55IGNv -bW1lbnRzIG9yIHJlbWFya3MgYWJvdXQgdGhpcyBwYXRjaD8gQW5kIGlmIHlvdSBkb24ndCBjb3Vs -ZCB5b3UgcGxlYXNlIGFwcGx5IGl0Lg0KDQpUaGFua3MhDQoNCi0tIA0KQmVzdCByZWdhcmRzLA0K -VmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+ +Hi Michael, Stephen, + +On Tue, 2017-02-21 at 16:11 +0300, Vlad Zakharov wrote: +> AXS10X boards manages it's clocks using various PLLs. These PLL has same +> dividers and corresponding control registers mapped to different addresses. +> So we add one common driver for such PLLs. +> +> Each PLL on AXS10X board consist of three dividers: IDIV, FBDIV and +> ODIV. Output clock value is managed using these dividers. +> +> We add pre-defined tables with supported rate values and appropriate +> configurations of IDIV, FBDIV and ODIV for each value. +> +> As of today we add support for PLLs that generate clock for the +> following devices: +> * ARC core on AXC CPU tiles. +> * ARC PGU on ARC SDP Mainboard. +> and more to come later. +> +> Acked-by: Rob Herring <robh@kernel.org> +> Signed-off-by: Vlad Zakharov <vzakhar@synopsys.com> +> Signed-off-by: Jose Abreu <joabreu@synopsys.com> +> Cc: Michael Turquette <mturquette@baylibre.com> +> Cc: Stephen Boyd <sboyd@codeaurora.org> +> Cc: Mark Rutland <mark.rutland@arm.com> +> --- +> Cc: Rob Herring <robh@kernel.org> +> Changes v1..v2 +> - Replace '_' with '-' in device tree nodes +> +> .../devicetree/bindings/clock/snps,pll-clock.txt | 28 ++ +> MAINTAINERS | 6 + +> drivers/clk/axs10x/Makefile | 1 + +> drivers/clk/axs10x/pll_clock.c | 384 +++++++++++++++++++++ +> 4 files changed, 419 insertions(+) +> create mode 100644 Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> create mode 100644 drivers/clk/axs10x/pll_clock.c +> +> diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> new file mode 100644 +> index 0000000..5706246 +> --- /dev/null +> +++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> @@ -0,0 +1,28 @@ +> +Binding for the AXS10X Generic PLL clock +> + +> +This binding uses the common clock binding[1]. +> + +> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +> + +> +Required properties: +> +- compatible: should be "snps,axs10x-<name>-pll-clock" +> + "snps,axs10x-arc-pll-clock" +> + "snps,axs10x-pgu-pll-clock" +> +- reg: should always contain 2 pairs address - length: first for PLL config +> +registers and second for corresponding LOCK CGU register. +> +- clocks: shall be the input parent clock phandle for the PLL. +> +- #clock-cells: from common clock binding; Should always be set to 0. +> + +> +Example: +> + input-clk: input-clk { +> + clock-frequency = <33333333>; +> + compatible = "fixed-clock"; +> + #clock-cells = <0>; +> + }; +> + +> + core-clk: core-clk@80 { +> + compatible = "snps,axs10x-arc-pll-clock"; +> + reg = <0x80 0x10 0x100 0x10>; +> + #clock-cells = <0>; +> + clocks = <&input-clk>; +> + }; +> diff --git a/MAINTAINERS b/MAINTAINERS +> index 3960e7f..5805833 100644 +> --- a/MAINTAINERS +> +++ b/MAINTAINERS +> @@ -11910,6 +11910,12 @@ F: arch/arc/plat-axs10x +> F: arch/arc/boot/dts/ax* +> F: Documentation/devicetree/bindings/arc/axs10* +> +> +SYNOPSYS ARC SDP clock driver +> +M: Vlad Zakharov <vzakhar@synopsys.com> +> +S: Supported +> +F: drivers/clk/axs10x/* +> +F: Documentation/devicetree/bindings/clock/snps,pll-clock.txt +> + +> SYSTEM CONFIGURATION (SYSCON) +> M: Lee Jones <lee.jones@linaro.org> +> M: Arnd Bergmann <arnd@arndb.de> +> diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile +> index 01996b8..d747dea 100644 +> --- a/drivers/clk/axs10x/Makefile +> +++ b/drivers/clk/axs10x/Makefile +> @@ -1 +1,2 @@ +> obj-y += i2s_pll_clock.o +> +obj-y += pll_clock.o +> diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c +> new file mode 100644 +> index 0000000..784a0a2 +> --- /dev/null +> +++ b/drivers/clk/axs10x/pll_clock.c +> @@ -0,0 +1,384 @@ +> +/* +> + * Synopsys AXS10X SDP Generic PLL clock driver +> + * +> + * Copyright (C) 2017 Synopsys +> + * +> + * This file is licensed under the terms of the GNU General Public +> + * License version 2. This program is licensed "as is" without any +> + * warranty of any kind, whether express or implied. +> + */ +> + +> +#include <linux/platform_device.h> +> +#include <linux/module.h> +> +#include <linux/clk-provider.h> +> +#include <linux/delay.h> +> +#include <linux/err.h> +> +#include <linux/device.h> +> +#include <linux/of_address.h> +> +#include <linux/of_device.h> +> +#include <linux/slab.h> +> +#include <linux/of.h> +> + +> +/* PLL registers addresses */ +> +#define PLL_REG_IDIV 0x0 +> +#define PLL_REG_FBDIV 0x4 +> +#define PLL_REG_ODIV 0x8 +> + +> +/* +> + * Bit fields of the PLL IDIV/FBDIV/ODIV registers: +> + * ________________________________________________________________________ +> + * |31 15| 14 | 13 | 12 |11 6|5 0| +> + * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--| +> + * |____________________|__________|________|______|____________|___________| +> + * +> + * Following macros detirmine the way of access to these registers +> + * They should be set up only using the macros. +> + * reg should be and uint32_t variable. +> + */ +> + +> +#define PLL_REG_GET_LOW(reg) \ +> + (((reg) & (0x3F << 0)) >> 0) +> +#define PLL_REG_GET_HIGH(reg) \ +> + (((reg) & (0x3F << 6)) >> 6) +> +#define PLL_REG_GET_EDGE(reg) \ +> + (((reg) & (BIT(12))) ? 1 : 0) +> +#define PLL_REG_GET_BYPASS(reg) \ +> + (((reg) & (BIT(13))) ? 1 : 0) +> +#define PLL_REG_GET_NOUPD(reg) \ +> + (((reg) & (BIT(14))) ? 1 : 0) +> +#define PLL_REG_GET_PAD(reg) \ +> + (((reg) & (0x1FFFF << 15)) >> 15) +> + +> +#define PLL_REG_SET_LOW(reg, value) \ +> + { reg |= (((value) & 0x3F) << 0); } +> +#define PLL_REG_SET_HIGH(reg, value) \ +> + { reg |= (((value) & 0x3F) << 6); } +> +#define PLL_REG_SET_EDGE(reg, value) \ +> + { reg |= (((value) & 0x01) << 12); } +> +#define PLL_REG_SET_BYPASS(reg, value) \ +> + { reg |= (((value) & 0x01) << 13); } +> +#define PLL_REG_SET_NOUPD(reg, value) \ +> + { reg |= (((value) & 0x01) << 14); } +> +#define PLL_REG_SET_PAD(reg, value) \ +> + { reg |= (((value) & 0x1FFFF) << 15); } +> + +> +#define PLL_LOCK 0x1 +> +#define PLL_MAX_LOCK_TIME 100 /* 100 us */ +> + +> +struct pll_cfg { +> + u32 rate; +> + u32 idiv; +> + u32 fbdiv; +> + u32 odiv; +> +}; +> + +> +struct pll_of_table { +> + unsigned long prate; +> + struct pll_cfg *pll_cfg_table; +> +}; +> + +> +struct pll_of_data { +> + struct pll_of_table *pll_table; +> +}; +> + +> +static struct pll_of_data pgu_pll_data = { +> + .pll_table = (struct pll_of_table []){ +> + { +> + .prate = 27000000, +> + .pll_cfg_table = (struct pll_cfg []){ +> + { 25200000, 1, 84, 90 }, +> + { 50000000, 1, 100, 54 }, +> + { 74250000, 1, 44, 16 }, +> + { }, +> + }, +> + }, +> + /* Used as list limiter */ +> + { }, +> + }, +> +}; +> + +> +static struct pll_of_data arc_pll_data = { +> + .pll_table = (struct pll_of_table []){ +> + { +> + .prate = 33333333, +> + .pll_cfg_table = (struct pll_cfg []){ +> + { 33333333, 1, 1, 1 }, +> + { 50000000, 1, 30, 20 }, +> + { 75000000, 2, 45, 10 }, +> + { 90000000, 2, 54, 10 }, +> + { 100000000, 1, 30, 10 }, +> + { 125000000, 2, 45, 6 }, +> + { }, +> + }, +> + }, +> + /* Used as list limiter */ +> + { }, +> + }, +> +}; +> + +> +struct pll_clk { +> + void __iomem *base; +> + void __iomem *lock; +> + const struct pll_of_data *pll_data; +> + struct clk_hw hw; +> + struct device *dev; +> +}; +> + +> +static inline void pll_write(struct pll_clk *clk, unsigned int reg, +> + unsigned int val) +> +{ +> + iowrite32(val, clk->base + reg); +> +} +> + +> +static inline u32 pll_read(struct pll_clk *clk, +> + unsigned int reg) +> +{ +> + return ioread32(clk->base + reg); +> +} +> + +> +static inline struct pll_clk *to_pll_clk(struct clk_hw *hw) +> +{ +> + return container_of(hw, struct pll_clk, hw); +> +} +> + +> +static inline u32 div_get_value(unsigned int reg) +> +{ +> + if (PLL_REG_GET_BYPASS(reg)) +> + return 1; +> + +> + return (PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg)); +> +} +> + +> +static inline u32 encode_div(unsigned int id, int upd) +> +{ +> + uint32_t div = 0; +> + +> + PLL_REG_SET_LOW(div, (id%2 == 0) ? id >> 1 : (id >> 1) + 1); +> + PLL_REG_SET_HIGH(div, id >> 1); +> + PLL_REG_SET_EDGE(div, id%2); +> + PLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0); +> + PLL_REG_SET_NOUPD(div, !upd); +> + +> + return div; +> +} +> + +> +static const struct pll_cfg *pll_get_cfg(unsigned long prate, +> + const struct pll_of_table *pll_table) +> +{ +> + int i; +> + +> + for (i = 0; pll_table[i].prate != 0; i++) +> + if (pll_table[i].prate == prate) +> + return pll_table[i].pll_cfg_table; +> + +> + return NULL; +> +} +> + +> +static unsigned long pll_recalc_rate(struct clk_hw *hw, +> + unsigned long parent_rate) +> +{ +> + u64 rate; +> + u32 idiv, fbdiv, odiv; +> + struct pll_clk *clk = to_pll_clk(hw); +> + +> + idiv = div_get_value(pll_read(clk, PLL_REG_IDIV)); +> + fbdiv = div_get_value(pll_read(clk, PLL_REG_FBDIV)); +> + odiv = div_get_value(pll_read(clk, PLL_REG_ODIV)); +> + +> + rate = (u64)parent_rate * fbdiv; +> + do_div(rate, idiv * odiv); +> + +> + return (unsigned long)rate; +> +} +> + +> +static long pll_round_rate(struct clk_hw *hw, unsigned long rate, +> + unsigned long *prate) +> +{ +> + int i; +> + long best_rate; +> + struct pll_clk *clk = to_pll_clk(hw); +> + const struct pll_cfg *pll_cfg = pll_get_cfg(*prate, +> + clk->pll_data->pll_table); +> + +> + if (!pll_cfg) { +> + dev_err(clk->dev, "invalid parent rate=%ld\n", *prate); +> + return -EINVAL; +> + } +> + +> + if (pll_cfg[0].rate == 0) +> + return -EINVAL; +> + +> + best_rate = pll_cfg[0].rate; +> + +> + for (i = 1; pll_cfg[i].rate != 0; i++) { +> + if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) +> + best_rate = pll_cfg[i].rate; +> + } +> + +> + return best_rate; +> +} +> + +> +static int pll_set_rate(struct clk_hw *hw, unsigned long rate, +> + unsigned long parent_rate) +> +{ +> + int i; +> + struct pll_clk *clk = to_pll_clk(hw); +> + const struct pll_cfg *pll_cfg = pll_get_cfg(parent_rate, +> + clk->pll_data->pll_table); +> + +> + if (!pll_cfg) { +> + dev_err(clk->dev, "invalid parent rate=%ld\n", parent_rate); +> + return -EINVAL; +> + } +> + +> + for (i = 0; pll_cfg[i].rate != 0; i++) { +> + if (pll_cfg[i].rate == rate) { +> + pll_write(clk, PLL_REG_IDIV, +> + encode_div(pll_cfg[i].idiv, 0)); +> + pll_write(clk, PLL_REG_FBDIV, +> + encode_div(pll_cfg[i].fbdiv, 0)); +> + pll_write(clk, PLL_REG_ODIV, +> + encode_div(pll_cfg[i].odiv, 1)); +> + +> + /* +> + * Wait until CGU relocks. +> + * If after timeout CGU is unlocked yet return error +> + */ +> + udelay(PLL_MAX_LOCK_TIME); +> + if (ioread32(clk->lock) & PLL_LOCK) +> + return 0; +> + else +> + return -ETIMEDOUT; +> + } +> + } +> + +> + dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate, +> + parent_rate); +> + return -EINVAL; +> +} +> + +> +static const struct clk_ops pll_ops = { +> + .recalc_rate = pll_recalc_rate, +> + .round_rate = pll_round_rate, +> + .set_rate = pll_set_rate, +> +}; +> + +> +static int pll_clk_probe(struct platform_device *pdev) +> +{ +> + struct device *dev = &pdev->dev; +> + const char *parent_name; +> + struct clk *clk; +> + struct pll_clk *pll_clk; +> + struct resource *mem; +> + struct clk_init_data init = { }; +> + +> + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); +> + if (!pll_clk) +> + return -ENOMEM; +> + +> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +> + pll_clk->base = devm_ioremap_resource(dev, mem); +> + if (IS_ERR(pll_clk->base)) +> + return PTR_ERR(pll_clk->base); +> + +> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); +> + pll_clk->lock = devm_ioremap_resource(dev, mem); +> + if (IS_ERR(pll_clk->lock)) +> + return PTR_ERR(pll_clk->base); +> + +> + init.name = dev->of_node->name; +> + init.ops = &pll_ops; +> + parent_name = of_clk_get_parent_name(dev->of_node, 0); +> + init.parent_names = &parent_name; +> + init.num_parents = 1; +> + pll_clk->hw.init = &init; +> + pll_clk->dev = dev; +> + pll_clk->pll_data = of_device_get_match_data(dev); +> + +> + if (!pll_clk->pll_data) { +> + dev_err(dev, "No OF match data provided\n"); +> + return -EINVAL; +> + } +> + +> + clk = devm_clk_register(dev, &pll_clk->hw); +> + if (IS_ERR(clk)) { +> + dev_err(dev, "failed to register %s clock (%ld)\n", +> + init.name, PTR_ERR(clk)); +> + return PTR_ERR(clk); +> + } +> + +> + return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, clk); +> +} +> + +> +static int pll_clk_remove(struct platform_device *pdev) +> +{ +> + of_clk_del_provider(pdev->dev.of_node); +> + return 0; +> +} +> + +> +static void __init of_pll_clk_setup(struct device_node *node) +> +{ +> + const char *parent_name; +> + struct clk *clk; +> + struct pll_clk *pll_clk; +> + struct clk_init_data init = { }; +> + +> + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); +> + if (!pll_clk) +> + return; +> + +> + pll_clk->base = of_iomap(node, 0); +> + if (!pll_clk->base) { +> + pr_err("failed to map pll div registers\n"); +> + iounmap(pll_clk->base); +> + return; +> + } +> + +> + pll_clk->lock = of_iomap(node, 1); +> + if (!pll_clk->lock) { +> + pr_err("failed to map pll lock register\n"); +> + iounmap(pll_clk->lock); +> + return; +> + } +> + +> + init.name = node->name; +> + init.ops = &pll_ops; +> + parent_name = of_clk_get_parent_name(node, 0); +> + init.parent_names = &parent_name; +> + init.num_parents = parent_name ? 1 : 0; +> + pll_clk->hw.init = &init; +> + pll_clk->pll_data = &arc_pll_data; +> + +> + clk = clk_register(NULL, &pll_clk->hw); +> + if (IS_ERR(clk)) { +> + pr_err("failed to register %s clock (%ld)\n", +> + node->name, PTR_ERR(clk)); +> + kfree(pll_clk); +> + return; +> + } +> + +> + of_clk_add_provider(node, of_clk_src_simple_get, clk); +> +} +> + +> +CLK_OF_DECLARE(axs10x_pll_clock, "snps,axs10x-arc-pll-clock", of_pll_clk_setup); +> + +> +static const struct of_device_id pll_clk_id[] = { +> + { .compatible = "snps,axs10x-arc-pll-clock", .data = &arc_pll_data}, +> + { .compatible = "snps,axs10x-pgu-pll-clock", .data = &pgu_pll_data}, +> + { }, +> +}; +> +MODULE_DEVICE_TABLE(of, pll_clk_id); +> + +> +static struct platform_driver pll_clk_driver = { +> + .driver = { +> + .name = "axs10x-pll-clock", +> + .of_match_table = pll_clk_id, +> + }, +> + .probe = pll_clk_probe, +> + .remove = pll_clk_remove, +> +}; +> +builtin_platform_driver(pll_clk_driver); +> + +> +MODULE_AUTHOR("Vlad Zakharov <vzakhar@synopsys.com>"); +> +MODULE_DESCRIPTION("Synopsys AXS10X SDP Generic PLL Clock Driver"); +> +MODULE_LICENSE("GPL v2"); + +Maybe you have any comments or remarks about this patch? And if you don't could you please apply it. + +Thanks! + +-- +Best regards, +Vlad Zakharov <vzakhar@synopsys.com> diff --git a/a/content_digest b/N3/content_digest index e97820e..21cf8db 100644 --- a/a/content_digest +++ b/N3/content_digest @@ -15,270 +15,500 @@ " sboyd@codeaurora.org <sboyd@codeaurora.org>\0" "\00:1\0" "b\0" - "SGkgTWljaGFlbCwgU3RlcGhlbiwNCg0KT24gVHVlLCAyMDE3LTAyLTIxIGF0IDE2OjExICswMzAw\n" - "LCBWbGFkIFpha2hhcm92IHdyb3RlOg0KPiBBWFMxMFggYm9hcmRzIG1hbmFnZXMgaXQncyBjbG9j\n" - "a3MgdXNpbmcgdmFyaW91cyBQTExzLiBUaGVzZSBQTEwgaGFzIHNhbWUNCj4gZGl2aWRlcnMgYW5k\n" - "IGNvcnJlc3BvbmRpbmcgY29udHJvbCByZWdpc3RlcnMgbWFwcGVkIHRvIGRpZmZlcmVudCBhZGRy\n" - "ZXNzZXMuDQo+IFNvIHdlIGFkZCBvbmUgY29tbW9uIGRyaXZlciBmb3Igc3VjaCBQTExzLg0KPiAN\n" - "Cj4gRWFjaCBQTEwgb24gQVhTMTBYIGJvYXJkIGNvbnNpc3Qgb2YgdGhyZWUgZGl2aWRlcnM6IElE\n" - "SVYsIEZCRElWIGFuZA0KPiBPRElWLiBPdXRwdXQgY2xvY2sgdmFsdWUgaXMgbWFuYWdlZCB1c2lu\n" - "ZyB0aGVzZSBkaXZpZGVycy4NCj4gDQo+IFdlIGFkZCBwcmUtZGVmaW5lZCB0YWJsZXMgd2l0aCBz\n" - "dXBwb3J0ZWQgcmF0ZSB2YWx1ZXMgYW5kIGFwcHJvcHJpYXRlDQo+IGNvbmZpZ3VyYXRpb25zIG9m\n" - "IElESVYsIEZCRElWIGFuZCBPRElWIGZvciBlYWNoIHZhbHVlLg0KPiANCj4gQXMgb2YgdG9kYXkg\n" - "d2UgYWRkIHN1cHBvcnQgZm9yIFBMTHMgdGhhdCBnZW5lcmF0ZSBjbG9jayBmb3IgdGhlDQo+IGZv\n" - "bGxvd2luZyBkZXZpY2VzOg0KPiDCoCogQVJDIGNvcmUgb24gQVhDIENQVSB0aWxlcy4NCj4gwqAq\n" - "IEFSQyBQR1Ugb24gQVJDIFNEUCBNYWluYm9hcmQuDQo+IGFuZCBtb3JlIHRvIGNvbWUgbGF0ZXIu\n" - "DQo+IA0KPiBBY2tlZC1ieTogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gU2lnbmVk\n" - "LW9mZi1ieTogVmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+DQo+IFNpZ25lZC1v\n" - "ZmYtYnk6IEpvc2UgQWJyZXUgPGpvYWJyZXVAc3lub3BzeXMuY29tPg0KPiBDYzogTWljaGFlbCBU\n" - "dXJxdWV0dGUgPG10dXJxdWV0dGVAYmF5bGlicmUuY29tPg0KPiBDYzogU3RlcGhlbiBCb3lkIDxz\n" - "Ym95ZEBjb2RlYXVyb3JhLm9yZz4NCj4gQ2M6IE1hcmsgUnV0bGFuZCA8bWFyay5ydXRsYW5kQGFy\n" - "bS5jb20+DQo+IC0tLQ0KPiBDYzogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9yZz4NCj4gQ2hh\n" - "bmdlcyB2MS4udjINCj4gwqAtIFJlcGxhY2UgJ18nIHdpdGggJy0nIGluIGRldmljZSB0cmVlIG5v\n" - "ZGVzDQo+IA0KPiDCoC4uLi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxsLWNsb2Nr\n" - "LnR4dMKgwqDCoHzCoMKgMjggKysNCj4gwqBNQUlOVEFJTkVSU8KgwqDCoMKgwqDCoMKgwqDCoMKg\n" - "wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC\n" - "oMKgfMKgwqDCoDYgKw0KPiDCoGRyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZcKgwqDCoMKgwqDC\n" - "oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHzCoMKgwqAxICsNCj4gwqBkcml2\n" - "ZXJzL2Nsay9heHMxMHgvcGxsX2Nsb2NrLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC\n" - "oMKgwqDCoMKgwqB8IDM4NCArKysrKysrKysrKysrKysrKysrKysNCj4gwqA0IGZpbGVzIGNoYW5n\n" - "ZWQsIDQxOSBpbnNlcnRpb25zKCspDQo+IMKgY3JlYXRlIG1vZGUgMTAwNjQ0IERvY3VtZW50YXRp\n" - "b24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gwqBjcmVh\n" - "dGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IA0KPiBkaWZm\n" - "IC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3NucHMscGxs\n" - "LWNsb2NrLnR4dA0KPiBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay9z\n" - "bnBzLHBsbC1jbG9jay50eHQNCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gaW5kZXggMDAwMDAw\n" - "MC4uNTcwNjI0Ng0KPiAtLS0gL2Rldi9udWxsDQo+ICsrKyBiL0RvY3VtZW50YXRpb24vZGV2aWNl\n" - "dHJlZS9iaW5kaW5ncy9jbG9jay9zbnBzLHBsbC1jbG9jay50eHQNCj4gQEAgLTAsMCArMSwyOCBA\n" - "QA0KPiArQmluZGluZyBmb3IgdGhlIEFYUzEwWCBHZW5lcmljIFBMTCBjbG9jaw0KPiArDQo+ICtU\n" - "aGlzIGJpbmRpbmcgdXNlcyB0aGUgY29tbW9uIGNsb2NrIGJpbmRpbmdbMV0uDQo+ICsNCj4gK1sx\n" - "XSBEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvY2xvY2svY2xvY2stYmluZGluZ3Mu\n" - "dHh0DQo+ICsNCj4gK1JlcXVpcmVkIHByb3BlcnRpZXM6DQo+ICstIGNvbXBhdGlibGU6IHNob3Vs\n" - "ZCBiZSAic25wcyxheHMxMHgtPG5hbWU+LXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgt\n" - "YXJjLXBsbC1jbG9jayINCj4gK8KgwqAic25wcyxheHMxMHgtcGd1LXBsbC1jbG9jayINCj4gKy0g\n" - "cmVnOiBzaG91bGQgYWx3YXlzIGNvbnRhaW4gMiBwYWlycyBhZGRyZXNzIC0gbGVuZ3RoOiBmaXJz\n" - "dCBmb3IgUExMIGNvbmZpZw0KPiArcmVnaXN0ZXJzIGFuZCBzZWNvbmQgZm9yIGNvcnJlc3BvbmRp\n" - "bmcgTE9DSyBDR1UgcmVnaXN0ZXIuDQo+ICstIGNsb2Nrczogc2hhbGwgYmUgdGhlIGlucHV0IHBh\n" - "cmVudCBjbG9jayBwaGFuZGxlIGZvciB0aGUgUExMLg0KPiArLSAjY2xvY2stY2VsbHM6IGZyb20g\n" - "Y29tbW9uIGNsb2NrIGJpbmRpbmc7IFNob3VsZCBhbHdheXMgYmUgc2V0IHRvIDAuDQo+ICsNCj4g\n" - "K0V4YW1wbGU6DQo+ICsJaW5wdXQtY2xrOiBpbnB1dC1jbGsgew0KPiArCQljbG9jay1mcmVxdWVu\n" - "Y3kgPSA8MzMzMzMzMzM+Ow0KPiArCQljb21wYXRpYmxlID0gImZpeGVkLWNsb2NrIjsNCj4gKwkJ\n" - "I2Nsb2NrLWNlbGxzID0gPDA+Ow0KPiArCX07DQo+ICsNCj4gKwljb3JlLWNsazogY29yZS1jbGtA\n" - "ODAgew0KPiArCQljb21wYXRpYmxlID0gInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2siOw0KPiAr\n" - "CQlyZWcgPSA8MHg4MCAweDEwIDB4MTAwIDB4MTA+Ow0KPiArCQkjY2xvY2stY2VsbHMgPSA8MD47\n" - "DQo+ICsJCWNsb2NrcyA9IDwmaW5wdXQtY2xrPjsNCj4gKwl9Ow0KPiBkaWZmIC0tZ2l0IGEvTUFJ\n" - "TlRBSU5FUlMgYi9NQUlOVEFJTkVSUw0KPiBpbmRleCAzOTYwZTdmLi41ODA1ODMzIDEwMDY0NA0K\n" - "PiAtLS0gYS9NQUlOVEFJTkVSUw0KPiArKysgYi9NQUlOVEFJTkVSUw0KPiBAQCAtMTE5MTAsNiAr\n" - "MTE5MTAsMTIgQEAgRjoJYXJjaC9hcmMvcGxhdC1heHMxMHgNCj4gwqBGOglhcmNoL2FyYy9ib290\n" - "L2R0cy9heCoNCj4gwqBGOglEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvYXJjL2F4\n" - "czEwKg0KPiDCoA0KPiArU1lOT1BTWVMgQVJDIFNEUCBjbG9jayBkcml2ZXINCj4gK006CVZsYWQg\n" - "WmFraGFyb3YgPHZ6YWtoYXJAc3lub3BzeXMuY29tPg0KPiArUzoJU3VwcG9ydGVkDQo+ICtGOglk\n" - "cml2ZXJzL2Nsay9heHMxMHgvKg0KPiArRjoJRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRp\n" - "bmdzL2Nsb2NrL3NucHMscGxsLWNsb2NrLnR4dA0KPiArDQo+IMKgU1lTVEVNIENPTkZJR1VSQVRJ\n" - "T04gKFNZU0NPTikNCj4gwqBNOglMZWUgSm9uZXMgPGxlZS5qb25lc0BsaW5hcm8ub3JnPg0KPiDC\n" - "oE06CUFybmQgQmVyZ21hbm4gPGFybmRAYXJuZGIuZGU+DQo+IGRpZmYgLS1naXQgYS9kcml2ZXJz\n" - "L2Nsay9heHMxMHgvTWFrZWZpbGUgYi9kcml2ZXJzL2Nsay9heHMxMHgvTWFrZWZpbGUNCj4gaW5k\n" - "ZXggMDE5OTZiOC4uZDc0N2RlYSAxMDA2NDQNCj4gLS0tIGEvZHJpdmVycy9jbGsvYXhzMTB4L01h\n" - "a2VmaWxlDQo+ICsrKyBiL2RyaXZlcnMvY2xrL2F4czEweC9NYWtlZmlsZQ0KPiBAQCAtMSArMSwy\n" - "IEBADQo+IMKgb2JqLXkgKz0gaTJzX3BsbF9jbG9jay5vDQo+ICtvYmoteSArPSBwbGxfY2xvY2su\n" - "bw0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jIGIvZHJpdmVy\n" - "cy9jbGsvYXhzMTB4L3BsbF9jbG9jay5jDQo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+IGluZGV4\n" - "IDAwMDAwMDAuLjc4NGEwYTINCj4gLS0tIC9kZXYvbnVsbA0KPiArKysgYi9kcml2ZXJzL2Nsay9h\n" - "eHMxMHgvcGxsX2Nsb2NrLmMNCj4gQEAgLTAsMCArMSwzODQgQEANCj4gKy8qDQo+ICsgKiBTeW5v\n" - "cHN5cyBBWFMxMFggU0RQIEdlbmVyaWMgUExMIGNsb2NrIGRyaXZlcg0KPiArICoNCj4gKyAqIENv\n" - "cHlyaWdodCAoQykgMjAxNyBTeW5vcHN5cw0KPiArICoNCj4gKyAqIFRoaXMgZmlsZSBpcyBsaWNl\n" - "bnNlZCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYw0KPiArICogTGlj\n" - "ZW5zZSB2ZXJzaW9uIDIuIFRoaXMgcHJvZ3JhbSBpcyBsaWNlbnNlZCAiYXMgaXMiIHdpdGhvdXQg\n" - "YW55DQo+ICsgKiB3YXJyYW50eSBvZiBhbnkga2luZCwgd2hldGhlciBleHByZXNzIG9yIGltcGxp\n" - "ZWQuDQo+ICsgKi8NCj4gKw0KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPg0K\n" - "PiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92\n" - "aWRlci5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+DQo+ICsjaW5jbHVkZSA8bGludXgv\n" - "ZXJyLmg+DQo+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ICsjaW5jbHVkZSA8bGludXgv\n" - "b2ZfYWRkcmVzcy5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPg0KPiArI2luY2x1\n" - "ZGUgPGxpbnV4L3NsYWIuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPg0KPiArDQo+ICsvKiBQ\n" - "TEwgcmVnaXN0ZXJzIGFkZHJlc3NlcyAqLw0KPiArI2RlZmluZSBQTExfUkVHX0lESVYJMHgwDQo+\n" - "ICsjZGVmaW5lIFBMTF9SRUdfRkJESVYJMHg0DQo+ICsjZGVmaW5lIFBMTF9SRUdfT0RJVgkweDgN\n" - "Cj4gKw0KPiArLyoNCj4gKyAqIEJpdCBmaWVsZHMgb2YgdGhlIFBMTCBJRElWL0ZCRElWL09ESVYg\n" - "cmVnaXN0ZXJzOg0KPiArICrCoMKgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f\n" - "X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQo+ICsgKiB8MzHCoMKgwqDCoMKg\n" - "wqDCoMKgwqDCoMKgwqDCoMKgwqDCoDE1fMKgwqDCoMKgMTTCoMKgwqDCoHzCoMKgwqAxM8KgwqDC\n" - "oHzCoMKgMTLCoMKgfDExwqDCoMKgwqDCoMKgwqDCoMKgNnw1wqDCoMKgwqDCoMKgwqDCoMKgMHwN\n" - "Cj4gKyAqIHwtLS0tLS0tUkVTUlZFRC0tLS0tLXwtTk9VUERBVEUtfC1CWVBBU1MtfC1FREdFLXwt\n" - "LUhJR0hUSU1FLS18LS1MT1dUSU1FLS18DQo+ICsgKiB8X19fX19fX19fX19fX19fX19fX198X19f\n" - "X19fX19fX3xfX19fX19fX3xfX19fX198X19fX19fX19fX19ffF9fX19fX19fX19ffA0KPiArICoN\n" - "Cj4gKyAqIEZvbGxvd2luZyBtYWNyb3MgZGV0aXJtaW5lIHRoZSB3YXkgb2YgYWNjZXNzIHRvIHRo\n" - "ZXNlIHJlZ2lzdGVycw0KPiArICogVGhleSBzaG91bGQgYmUgc2V0IHVwIG9ubHkgdXNpbmcgdGhl\n" - "IG1hY3Jvcy4NCj4gKyAqIHJlZyBzaG91bGQgYmUgYW5kIHVpbnQzMl90IHZhcmlhYmxlLg0KPiAr\n" - "ICovDQo+ICsNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTE9XKHJlZykJCQlcDQo+ICsJKCgocmVn\n" - "KSAmICgweDNGIDw8IDApKSA+PiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9ISUdIKHJlZykJ\n" - "CQlcDQo+ICsJKCgocmVnKSAmICgweDNGIDw8IDYpKSA+PiA2KQ0KPiArI2RlZmluZSBQTExfUkVH\n" - "X0dFVF9FREdFKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQoMTIpKSkgPyAxIDogMCkNCj4g\n" - "KyNkZWZpbmUgUExMX1JFR19HRVRfQllQQVNTKHJlZykJCQlcDQo+ICsJKCgocmVnKSAmIChCSVQo\n" - "MTMpKSkgPyAxIDogMCkNCj4gKyNkZWZpbmUgUExMX1JFR19HRVRfTk9VUEQocmVnKQkJCVwNCj4g\n" - "KwkoKChyZWcpICYgKEJJVCgxNCkpKSA/IDEgOiAwKQ0KPiArI2RlZmluZSBQTExfUkVHX0dFVF9Q\n" - "QUQocmVnKQkJCVwNCj4gKwkoKChyZWcpICYgKDB4MUZGRkYgPDwgMTUpKSA+PiAxNSkNCj4gKw0K\n" - "PiArI2RlZmluZSBQTExfUkVHX1NFVF9MT1cocmVnLCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAo\n" - "KCh2YWx1ZSkgJiAweDNGKSA8PCAwKTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9ISUdIKHJl\n" - "ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDNGKSA8PCA2KTsgfQ0KPiAr\n" - "I2RlZmluZSBQTExfUkVHX1NFVF9FREdFKHJlZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2\n" - "YWx1ZSkgJiAweDAxKSA8PCAxMik7IH0NCj4gKyNkZWZpbmUgUExMX1JFR19TRVRfQllQQVNTKHJl\n" - "ZywgdmFsdWUpCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDAxKSA8PCAxMyk7IH0NCj4g\n" - "KyNkZWZpbmUgUExMX1JFR19TRVRfTk9VUEQocmVnLCB2YWx1ZSkJXA0KPiArCXsgcmVnIHw9ICgo\n" - "KHZhbHVlKSAmIDB4MDEpIDw8IDE0KTsgfQ0KPiArI2RlZmluZSBQTExfUkVHX1NFVF9QQUQocmVn\n" - "LCB2YWx1ZSkJCVwNCj4gKwl7IHJlZyB8PSAoKCh2YWx1ZSkgJiAweDFGRkZGKSA8PCAxNSk7IH0N\n" - "Cj4gKw0KPiArI2RlZmluZSBQTExfTE9DSwkweDENCj4gKyNkZWZpbmUgUExMX01BWF9MT0NLX1RJ\n" - "TUUgMTAwIC8qIDEwMCB1cyAqLw0KPiArDQo+ICtzdHJ1Y3QgcGxsX2NmZyB7DQo+ICsJdTMyIHJh\n" - "dGU7DQo+ICsJdTMyIGlkaXY7DQo+ICsJdTMyIGZiZGl2Ow0KPiArCXUzMiBvZGl2Ow0KPiArfTsN\n" - "Cj4gKw0KPiArc3RydWN0IHBsbF9vZl90YWJsZSB7DQo+ICsJdW5zaWduZWQgbG9uZyBwcmF0ZTsN\n" - "Cj4gKwlzdHJ1Y3QgcGxsX2NmZyAqcGxsX2NmZ190YWJsZTsNCj4gK307DQo+ICsNCj4gK3N0cnVj\n" - "dCBwbGxfb2ZfZGF0YSB7DQo+ICsJc3RydWN0IHBsbF9vZl90YWJsZSAqcGxsX3RhYmxlOw0KPiAr\n" - "fTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2ZfZGF0YSBwZ3VfcGxsX2RhdGEgPSB7DQo+\n" - "ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3RhYmxlIFtdKXsNCj4gKwkJew0KPiArCQkJ\n" - "LnByYXRlID0gMjcwMDAwMDAsDQo+ICsJCQkucGxsX2NmZ190YWJsZSA9IChzdHJ1Y3QgcGxsX2Nm\n" - "ZyBbXSl7DQo+ICsJCQkJeyAyNTIwMDAwMCwgMSwgODQsIDkwIH0sDQo+ICsJCQkJeyA1MDAwMDAw\n" - "MCwgMSwgMTAwLCA1NCB9LA0KPiArCQkJCXsgNzQyNTAwMDAsIDEsIDQ0LCAxNiB9LA0KPiArCQkJ\n" - "CXsgfSwNCj4gKwkJCX0sDQo+ICsJCX0sDQo+ICsJCS8qIFVzZWQgYXMgbGlzdCBsaW1pdGVyICov\n" - "DQo+ICsJCXsgfSwNCj4gKwl9LA0KPiArfTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBwbGxfb2Zf\n" - "ZGF0YSBhcmNfcGxsX2RhdGEgPSB7DQo+ICsJLnBsbF90YWJsZSA9IChzdHJ1Y3QgcGxsX29mX3Rh\n" - "YmxlIFtdKXsNCj4gKwkJew0KPiArCQkJLnByYXRlID0gMzMzMzMzMzMsDQo+ICsJCQkucGxsX2Nm\n" - "Z190YWJsZSA9IChzdHJ1Y3QgcGxsX2NmZyBbXSl7DQo+ICsJCQkJeyAzMzMzMzMzMyzCoMKgMSwg\n" - "MSzCoMKgMSB9LA0KPiArCQkJCXsgNTAwMDAwMDAswqDCoDEsIDMwLCAyMCB9LA0KPiArCQkJCXsg\n" - "NzUwMDAwMDAswqDCoDIsIDQ1LCAxMCB9LA0KPiArCQkJCXsgOTAwMDAwMDAswqDCoDIsIDU0LCAx\n" - "MCB9LA0KPiArCQkJCXsgMTAwMDAwMDAwLCAxLCAzMCwgMTAgfSwNCj4gKwkJCQl7IDEyNTAwMDAw\n" - "MCwgMiwgNDUsIDYgfSwNCj4gKwkJCQl7IH0sDQo+ICsJCQl9LA0KPiArCQl9LA0KPiArCQkvKiBV\n" - "c2VkIGFzIGxpc3QgbGltaXRlciAqLw0KPiArCQl7IH0sDQo+ICsJfSwNCj4gK307DQo+ICsNCj4g\n" - "K3N0cnVjdCBwbGxfY2xrIHsNCj4gKwl2b2lkIF9faW9tZW0gKmJhc2U7DQo+ICsJdm9pZCBfX2lv\n" - "bWVtICpsb2NrOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfb2ZfZGF0YSAqcGxsX2RhdGE7DQo+ICsJ\n" - "c3RydWN0IGNsa19odyBodzsNCj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7DQo+ICt9Ow0KPiArDQo+\n" - "ICtzdGF0aWMgaW5saW5lIHZvaWQgcGxsX3dyaXRlKHN0cnVjdCBwbGxfY2xrICpjbGssIHVuc2ln\n" - "bmVkIGludCByZWcsDQo+ICsJCXVuc2lnbmVkIGludCB2YWwpDQo+ICt7DQo+ICsJaW93cml0ZTMy\n" - "KHZhbCwgY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiArc3RhdGljIGlubGluZSB1MzIg\n" - "cGxsX3JlYWQoc3RydWN0IHBsbF9jbGsgKmNsaywNCj4gKwkJdW5zaWduZWQgaW50IHJlZykNCj4g\n" - "K3sNCj4gKwlyZXR1cm4gaW9yZWFkMzIoY2xrLT5iYXNlICsgcmVnKTsNCj4gK30NCj4gKw0KPiAr\n" - "c3RhdGljIGlubGluZSBzdHJ1Y3QgcGxsX2NsayAqdG9fcGxsX2NsayhzdHJ1Y3QgY2xrX2h3ICpo\n" - "dykNCj4gK3sNCj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGh3LCBzdHJ1Y3QgcGxsX2NsaywgaHcp\n" - "Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBkaXZfZ2V0X3ZhbHVlKHVuc2lnbmVk\n" - "IGludCByZWcpDQo+ICt7DQo+ICsJaWYgKFBMTF9SRUdfR0VUX0JZUEFTUyhyZWcpKQ0KPiArCQly\n" - "ZXR1cm4gMTsNCj4gKw0KPiArCXJldHVybiAoUExMX1JFR19HRVRfSElHSChyZWcpICsgUExMX1JF\n" - "R19HRVRfTE9XKHJlZykpOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW5saW5lIHUzMiBlbmNvZGVf\n" - "ZGl2KHVuc2lnbmVkIGludCBpZCwgaW50IHVwZCkNCj4gK3sNCj4gKwl1aW50MzJfdCBkaXYgPSAw\n" - "Ow0KPiArDQo+ICsJUExMX1JFR19TRVRfTE9XKGRpdiwgKGlkJTIgPT0gMCkgPyBpZCA+PiAxIDog\n" - "KGlkID4+IDEpICsgMSk7DQo+ICsJUExMX1JFR19TRVRfSElHSChkaXYsIGlkID4+IDEpOw0KPiAr\n" - "CVBMTF9SRUdfU0VUX0VER0UoZGl2LCBpZCUyKTsNCj4gKwlQTExfUkVHX1NFVF9CWVBBU1MoZGl2\n" - "LCBpZCA9PSAxID8gMSA6IDApOw0KPiArCVBMTF9SRUdfU0VUX05PVVBEKGRpdiwgIXVwZCk7DQo+\n" - "ICsNCj4gKwlyZXR1cm4gZGl2Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHBs\n" - "bF9jZmcgKnBsbF9nZXRfY2ZnKHVuc2lnbmVkIGxvbmcgcHJhdGUsDQo+ICsJCWNvbnN0IHN0cnVj\n" - "dCBwbGxfb2ZfdGFibGUgKnBsbF90YWJsZSkNCj4gK3sNCj4gKwlpbnQgaTsNCj4gKw0KPiArCWZv\n" - "ciAoaSA9IDA7IHBsbF90YWJsZVtpXS5wcmF0ZSAhPSAwOyBpKyspDQo+ICsJCWlmIChwbGxfdGFi\n" - "bGVbaV0ucHJhdGUgPT0gcHJhdGUpDQo+ICsJCQlyZXR1cm4gcGxsX3RhYmxlW2ldLnBsbF9jZmdf\n" - "dGFibGU7DQo+ICsNCj4gKwlyZXR1cm4gTlVMTDsNCj4gK30NCj4gKw0KPiArc3RhdGljIHVuc2ln\n" - "bmVkIGxvbmcgcGxsX3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LA0KPiArCQkJdW5zaWdu\n" - "ZWQgbG9uZyBwYXJlbnRfcmF0ZSkNCj4gK3sNCj4gKwl1NjQgcmF0ZTsNCj4gKwl1MzIgaWRpdiwg\n" - "ZmJkaXYsIG9kaXY7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcpOw0K\n" - "PiArDQo+ICsJaWRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0lESVYp\n" - "KTsNCj4gKwlmYmRpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX0ZCRElW\n" - "KSk7DQo+ICsJb2RpdiA9IGRpdl9nZXRfdmFsdWUocGxsX3JlYWQoY2xrLCBQTExfUkVHX09ESVYp\n" - "KTsNCj4gKw0KPiArCXJhdGUgPSAodTY0KXBhcmVudF9yYXRlICogZmJkaXY7DQo+ICsJZG9fZGl2\n" - "KHJhdGUsIGlkaXYgKiBvZGl2KTsNCj4gKw0KPiArCXJldHVybiAodW5zaWduZWQgbG9uZylyYXRl\n" - "Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgbG9uZyBwbGxfcm91bmRfcmF0ZShzdHJ1Y3QgY2xrX2h3\n" - "ICpodywgdW5zaWduZWQgbG9uZyByYXRlLA0KPiArCQkJdW5zaWduZWQgbG9uZyAqcHJhdGUpDQo+\n" - "ICt7DQo+ICsJaW50IGk7DQo+ICsJbG9uZyBiZXN0X3JhdGU7DQo+ICsJc3RydWN0IHBsbF9jbGsg\n" - "KmNsayA9IHRvX3BsbF9jbGsoaHcpOw0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2Zn\n" - "ID0gcGxsX2dldF9jZmcoKnByYXRlLA0KPiArCQkJY2xrLT5wbGxfZGF0YS0+cGxsX3RhYmxlKTsN\n" - "Cj4gKw0KPiArCWlmICghcGxsX2NmZykgew0KPiArCQlkZXZfZXJyKGNsay0+ZGV2LCAiaW52YWxp\n" - "ZCBwYXJlbnQgcmF0ZT0lbGRcbiIsICpwcmF0ZSk7DQo+ICsJCXJldHVybiAtRUlOVkFMOw0KPiAr\n" - "CX0NCj4gKw0KPiArCWlmIChwbGxfY2ZnWzBdLnJhdGUgPT0gMCkNCj4gKwkJcmV0dXJuIC1FSU5W\n" - "QUw7DQo+ICsNCj4gKwliZXN0X3JhdGUgPSBwbGxfY2ZnWzBdLnJhdGU7DQo+ICsNCj4gKwlmb3Ig\n" - "KGkgPSAxOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChhYnMocmF0ZSAt\n" - "IHBsbF9jZmdbaV0ucmF0ZSkgPCBhYnMocmF0ZSAtIGJlc3RfcmF0ZSkpDQo+ICsJCQliZXN0X3Jh\n" - "dGUgPSBwbGxfY2ZnW2ldLnJhdGU7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIGJlc3RfcmF0ZTsN\n" - "Cj4gK30NCj4gKw0KPiArc3RhdGljIGludCBwbGxfc2V0X3JhdGUoc3RydWN0IGNsa19odyAqaHcs\n" - "IHVuc2lnbmVkIGxvbmcgcmF0ZSwNCj4gKwkJCXVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpDQo+\n" - "ICt7DQo+ICsJaW50IGk7DQo+ICsJc3RydWN0IHBsbF9jbGsgKmNsayA9IHRvX3BsbF9jbGsoaHcp\n" - "Ow0KPiArCWNvbnN0IHN0cnVjdCBwbGxfY2ZnICpwbGxfY2ZnID0gcGxsX2dldF9jZmcocGFyZW50\n" - "X3JhdGUsDQo+ICsJCQljbGstPnBsbF9kYXRhLT5wbGxfdGFibGUpOw0KPiArDQo+ICsJaWYgKCFw\n" - "bGxfY2ZnKSB7DQo+ICsJCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHBhcmVudCByYXRlPSVs\n" - "ZFxuIiwgcGFyZW50X3JhdGUpOw0KPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gKwl9DQo+ICsNCj4g\n" - "Kwlmb3IgKGkgPSAwOyBwbGxfY2ZnW2ldLnJhdGUgIT0gMDsgaSsrKSB7DQo+ICsJCWlmIChwbGxf\n" - "Y2ZnW2ldLnJhdGUgPT0gcmF0ZSkgew0KPiArCQkJcGxsX3dyaXRlKGNsaywgUExMX1JFR19JRElW\n" - "LA0KPiArCQkJCQllbmNvZGVfZGl2KHBsbF9jZmdbaV0uaWRpdiwgMCkpOw0KPiArCQkJcGxsX3dy\n" - "aXRlKGNsaywgUExMX1JFR19GQkRJViwNCj4gKwkJCQkJZW5jb2RlX2RpdihwbGxfY2ZnW2ldLmZi\n" - "ZGl2LCAwKSk7DQo+ICsJCQlwbGxfd3JpdGUoY2xrLCBQTExfUkVHX09ESVYsDQo+ICsJCQkJCWVu\n" - "Y29kZV9kaXYocGxsX2NmZ1tpXS5vZGl2LCAxKSk7DQo+ICsNCj4gKwkJCS8qDQo+ICsJCQnCoCog\n" - "V2FpdCB1bnRpbCBDR1UgcmVsb2Nrcy4NCj4gKwkJCcKgKiBJZiBhZnRlciB0aW1lb3V0IENHVSBp\n" - "cyB1bmxvY2tlZCB5ZXQgcmV0dXJuIGVycm9yDQo+ICsJCQnCoCovDQo+ICsJCQl1ZGVsYXkoUExM\n" - "X01BWF9MT0NLX1RJTUUpOw0KPiArCQkJaWYgKGlvcmVhZDMyKGNsay0+bG9jaykgJiBQTExfTE9D\n" - "SykNCj4gKwkJCQlyZXR1cm4gMDsNCj4gKwkJCWVsc2UNCj4gKwkJCQlyZXR1cm4gLUVUSU1FRE9V\n" - "VDsNCj4gKwkJfQ0KPiArCX0NCj4gKw0KPiArCWRldl9lcnIoY2xrLT5kZXYsICJpbnZhbGlkIHJh\n" - "dGU9JWxkLCBwYXJlbnRfcmF0ZT0lbGRcbiIsIHJhdGUsDQo+ICsJCQlwYXJlbnRfcmF0ZSk7DQo+\n" - "ICsJcmV0dXJuIC1FSU5WQUw7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY2xr\n" - "X29wcyBwbGxfb3BzID0gew0KPiArCS5yZWNhbGNfcmF0ZSA9IHBsbF9yZWNhbGNfcmF0ZSwNCj4g\n" - "Kwkucm91bmRfcmF0ZSA9IHBsbF9yb3VuZF9yYXRlLA0KPiArCS5zZXRfcmF0ZSA9IHBsbF9zZXRf\n" - "cmF0ZSwNCj4gK307DQo+ICsNCj4gK3N0YXRpYyBpbnQgcGxsX2Nsa19wcm9iZShzdHJ1Y3QgcGxh\n" - "dGZvcm1fZGV2aWNlICpwZGV2KQ0KPiArew0KPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2\n" - "LT5kZXY7DQo+ICsJY29uc3QgY2hhciAqcGFyZW50X25hbWU7DQo+ICsJc3RydWN0IGNsayAqY2xr\n" - "Ow0KPiArCXN0cnVjdCBwbGxfY2xrICpwbGxfY2xrOw0KPiArCXN0cnVjdCByZXNvdXJjZSAqbWVt\n" - "Ow0KPiArCXN0cnVjdCBjbGtfaW5pdF9kYXRhIGluaXQgPSB7IH07DQo+ICsNCj4gKwlwbGxfY2xr\n" - "ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJ\n" - "aWYgKCFwbGxfY2xrKQ0KPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gKw0KPiArCW1lbSA9IHBsYXRm\n" - "b3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7DQo+ICsJcGxsX2Nsay0+\n" - "YmFzZSA9IGRldm1faW9yZW1hcF9yZXNvdXJjZShkZXYsIG1lbSk7DQo+ICsJaWYgKElTX0VSUihw\n" - "bGxfY2xrLT5iYXNlKSkNCj4gKwkJcmV0dXJuIFBUUl9FUlIocGxsX2Nsay0+YmFzZSk7DQo+ICsN\n" - "Cj4gKwltZW0gPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDEp\n" - "Ow0KPiArCXBsbF9jbGstPmxvY2sgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCBtZW0pOw0K\n" - "PiArCWlmIChJU19FUlIocGxsX2Nsay0+bG9jaykpDQo+ICsJCXJldHVybiBQVFJfRVJSKHBsbF9j\n" - "bGstPmJhc2UpOw0KPiArDQo+ICsJaW5pdC5uYW1lID0gZGV2LT5vZl9ub2RlLT5uYW1lOw0KPiAr\n" - "CWluaXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVu\n" - "dF9uYW1lKGRldi0+b2Zfbm9kZSwgMCk7DQo+ICsJaW5pdC5wYXJlbnRfbmFtZXMgPSAmcGFyZW50\n" - "X25hbWU7DQo+ICsJaW5pdC5udW1fcGFyZW50cyA9IDE7DQo+ICsJcGxsX2Nsay0+aHcuaW5pdCA9\n" - "ICZpbml0Ow0KPiArCXBsbF9jbGstPmRldiA9IGRldjsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9\n" - "IG9mX2RldmljZV9nZXRfbWF0Y2hfZGF0YShkZXYpOw0KPiArDQo+ICsJaWYgKCFwbGxfY2xrLT5w\n" - "bGxfZGF0YSkgew0KPiArCQlkZXZfZXJyKGRldiwgIk5vIE9GIG1hdGNoIGRhdGEgcHJvdmlkZWRc\n" - "biIpOw0KPiArCQkJcmV0dXJuIC1FSU5WQUw7DQo+ICsJfQ0KPiArDQo+ICsJY2xrID0gZGV2bV9j\n" - "bGtfcmVnaXN0ZXIoZGV2LCAmcGxsX2Nsay0+aHcpOw0KPiArCWlmIChJU19FUlIoY2xrKSkgew0K\n" - "PiArCQlkZXZfZXJyKGRldiwgImZhaWxlZCB0byByZWdpc3RlciAlcyBjbG9jayAoJWxkKVxuIiwN\n" - "Cj4gKwkJCQlpbml0Lm5hbWUsIFBUUl9FUlIoY2xrKSk7DQo+ICsJCXJldHVybiBQVFJfRVJSKGNs\n" - "ayk7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIG9mX2Nsa19hZGRfcHJvdmlkZXIoZGV2LT5vZl9u\n" - "b2RlLCBvZl9jbGtfc3JjX3NpbXBsZV9nZXQsIGNsayk7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBp\n" - "bnQgcGxsX2Nsa19yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gK3sNCj4g\n" - "KwlvZl9jbGtfZGVsX3Byb3ZpZGVyKHBkZXYtPmRldi5vZl9ub2RlKTsNCj4gKwlyZXR1cm4gMDsN\n" - "Cj4gK30NCj4gKw0KPiArc3RhdGljIHZvaWQgX19pbml0IG9mX3BsbF9jbGtfc2V0dXAoc3RydWN0\n" - "IGRldmljZV9ub2RlICpub2RlKQ0KPiArew0KPiArCWNvbnN0IGNoYXIgKnBhcmVudF9uYW1lOw0K\n" - "PiArCXN0cnVjdCBjbGsgKmNsazsNCj4gKwlzdHJ1Y3QgcGxsX2NsayAqcGxsX2NsazsNCj4gKwlz\n" - "dHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0ID0geyB9Ow0KPiArDQo+ICsJcGxsX2NsayA9IGt6YWxs\n" - "b2Moc2l6ZW9mKCpwbGxfY2xrKSwgR0ZQX0tFUk5FTCk7DQo+ICsJaWYgKCFwbGxfY2xrKQ0KPiAr\n" - "CQlyZXR1cm47DQo+ICsNCj4gKwlwbGxfY2xrLT5iYXNlID0gb2ZfaW9tYXAobm9kZSwgMCk7DQo+\n" - "ICsJaWYgKCFwbGxfY2xrLT5iYXNlKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBwbGwg\n" - "ZGl2IHJlZ2lzdGVyc1xuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+YmFzZSk7DQo+ICsJCXJl\n" - "dHVybjsNCj4gKwl9DQo+ICsNCj4gKwlwbGxfY2xrLT5sb2NrID0gb2ZfaW9tYXAobm9kZSwgMSk7\n" - "DQo+ICsJaWYgKCFwbGxfY2xrLT5sb2NrKSB7DQo+ICsJCXByX2VycigiZmFpbGVkIHRvIG1hcCBw\n" - "bGwgbG9jayByZWdpc3RlclxuIik7DQo+ICsJCWlvdW5tYXAocGxsX2Nsay0+bG9jayk7DQo+ICsJ\n" - "CXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlpbml0Lm5hbWUgPSBub2RlLT5uYW1lOw0KPiArCWlu\n" - "aXQub3BzID0gJnBsbF9vcHM7DQo+ICsJcGFyZW50X25hbWUgPSBvZl9jbGtfZ2V0X3BhcmVudF9u\n" - "YW1lKG5vZGUsIDApOw0KPiArCWluaXQucGFyZW50X25hbWVzID0gJnBhcmVudF9uYW1lOw0KPiAr\n" - "CWluaXQubnVtX3BhcmVudHMgPSBwYXJlbnRfbmFtZSA/IDEgOiAwOw0KPiArCXBsbF9jbGstPmh3\n" - "LmluaXQgPSAmaW5pdDsNCj4gKwlwbGxfY2xrLT5wbGxfZGF0YSA9ICZhcmNfcGxsX2RhdGE7DQo+\n" - "ICsNCj4gKwljbGsgPSBjbGtfcmVnaXN0ZXIoTlVMTCwgJnBsbF9jbGstPmh3KTsNCj4gKwlpZiAo\n" - "SVNfRVJSKGNsaykpIHsNCj4gKwkJcHJfZXJyKCJmYWlsZWQgdG8gcmVnaXN0ZXIgJXMgY2xvY2sg\n" - "KCVsZClcbiIsDQo+ICsJCQkJbm9kZS0+bmFtZSwgUFRSX0VSUihjbGspKTsNCj4gKwkJa2ZyZWUo\n" - "cGxsX2Nsayk7DQo+ICsJCXJldHVybjsNCj4gKwl9DQo+ICsNCj4gKwlvZl9jbGtfYWRkX3Byb3Zp\n" - "ZGVyKG5vZGUsIG9mX2Nsa19zcmNfc2ltcGxlX2dldCwgY2xrKTsNCj4gK30NCj4gKw0KPiArQ0xL\n" - "X09GX0RFQ0xBUkUoYXhzMTB4X3BsbF9jbG9jaywgInNucHMsYXhzMTB4LWFyYy1wbGwtY2xvY2si\n" - "LCBvZl9wbGxfY2xrX3NldHVwKTsNCj4gKw0KPiArc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp\n" - "Y2VfaWQgcGxsX2Nsa19pZFtdID0gew0KPiArCXsgLmNvbXBhdGlibGUgPSAic25wcyxheHMxMHgt\n" - "YXJjLXBsbC1jbG9jayIsIC5kYXRhID0gJmFyY19wbGxfZGF0YX0sDQo+ICsJeyAuY29tcGF0aWJs\n" - "ZSA9ICJzbnBzLGF4czEweC1wZ3UtcGxsLWNsb2NrIiwgLmRhdGEgPSAmcGd1X3BsbF9kYXRhfSwN\n" - "Cj4gKwl7IH0sDQo+ICt9Ow0KPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgcGxsX2Nsa19pZCk7\n" - "DQo+ICsNCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIHBsbF9jbGtfZHJpdmVyID0g\n" - "ew0KPiArCS5kcml2ZXIgPSB7DQo+ICsJCS5uYW1lID0gImF4czEweC1wbGwtY2xvY2siLA0KPiAr\n" - "CQkub2ZfbWF0Y2hfdGFibGUgPSBwbGxfY2xrX2lkLA0KPiArCX0sDQo+ICsJLnByb2JlID0gcGxs\n" - "X2Nsa19wcm9iZSwNCj4gKwkucmVtb3ZlID0gcGxsX2Nsa19yZW1vdmUsDQo+ICt9Ow0KPiArYnVp\n" - "bHRpbl9wbGF0Zm9ybV9kcml2ZXIocGxsX2Nsa19kcml2ZXIpOw0KPiArDQo+ICtNT0RVTEVfQVVU\n" - "SE9SKCJWbGFkIFpha2hhcm92IDx2emFraGFyQHN5bm9wc3lzLmNvbT4iKTsNCj4gK01PRFVMRV9E\n" - "RVNDUklQVElPTigiU3lub3BzeXMgQVhTMTBYIFNEUCBHZW5lcmljIFBMTCBDbG9jayBEcml2ZXIi\n" - "KTsNCj4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsNCg0KTWF5YmUgeW91IGhhdmUgYW55IGNv\n" - "bW1lbnRzIG9yIHJlbWFya3MgYWJvdXQgdGhpcyBwYXRjaD8gQW5kIGlmIHlvdSBkb24ndCBjb3Vs\n" - "ZCB5b3UgcGxlYXNlIGFwcGx5IGl0Lg0KDQpUaGFua3MhDQoNCi0tIA0KQmVzdCByZWdhcmRzLA0K\n" - VmxhZCBaYWtoYXJvdiA8dnpha2hhckBzeW5vcHN5cy5jb20+ + "Hi Michael, Stephen,\n" + "\n" + "On Tue, 2017-02-21 at 16:11 +0300, Vlad Zakharov wrote:\n" + "> AXS10X boards manages it's clocks using various PLLs. These PLL has same\n" + "> dividers and corresponding control registers mapped to different addresses.\n" + "> So we add one common driver for such PLLs.\n" + "> \n" + "> Each PLL on AXS10X board consist of three dividers: IDIV, FBDIV and\n" + "> ODIV. Output clock value is managed using these dividers.\n" + "> \n" + "> We add pre-defined tables with supported rate values and appropriate\n" + "> configurations of IDIV, FBDIV and ODIV for each value.\n" + "> \n" + "> As of today we add support for PLLs that generate clock for the\n" + "> following devices:\n" + "> \302\240* ARC core on AXC CPU tiles.\n" + "> \302\240* ARC PGU on ARC SDP Mainboard.\n" + "> and more to come later.\n" + "> \n" + "> Acked-by: Rob Herring <robh@kernel.org>\n" + "> Signed-off-by: Vlad Zakharov <vzakhar@synopsys.com>\n" + "> Signed-off-by: Jose Abreu <joabreu@synopsys.com>\n" + "> Cc: Michael Turquette <mturquette@baylibre.com>\n" + "> Cc: Stephen Boyd <sboyd@codeaurora.org>\n" + "> Cc: Mark Rutland <mark.rutland@arm.com>\n" + "> ---\n" + "> Cc: Rob Herring <robh@kernel.org>\n" + "> Changes v1..v2\n" + "> \302\240- Replace '_' with '-' in device tree nodes\n" + "> \n" + "> \302\240.../devicetree/bindings/clock/snps,pll-clock.txt\302\240\302\240\302\240|\302\240\302\24028 ++\n" + "> \302\240MAINTAINERS\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240|\302\240\302\240\302\2406 +\n" + "> \302\240drivers/clk/axs10x/Makefile\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240|\302\240\302\240\302\2401 +\n" + "> \302\240drivers/clk/axs10x/pll_clock.c\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240| 384 +++++++++++++++++++++\n" + "> \302\2404 files changed, 419 insertions(+)\n" + "> \302\240create mode 100644 Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> \302\240create mode 100644 drivers/clk/axs10x/pll_clock.c\n" + "> \n" + "> diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> new file mode 100644\n" + "> index 0000000..5706246\n" + "> --- /dev/null\n" + "> +++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> @@ -0,0 +1,28 @@\n" + "> +Binding for the AXS10X Generic PLL clock\n" + "> +\n" + "> +This binding uses the common clock binding[1].\n" + "> +\n" + "> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt\n" + "> +\n" + "> +Required properties:\n" + "> +- compatible: should be \"snps,axs10x-<name>-pll-clock\"\n" + "> +\302\240\302\240\"snps,axs10x-arc-pll-clock\"\n" + "> +\302\240\302\240\"snps,axs10x-pgu-pll-clock\"\n" + "> +- reg: should always contain 2 pairs address - length: first for PLL config\n" + "> +registers and second for corresponding LOCK CGU register.\n" + "> +- clocks: shall be the input parent clock phandle for the PLL.\n" + "> +- #clock-cells: from common clock binding; Should always be set to 0.\n" + "> +\n" + "> +Example:\n" + "> +\tinput-clk: input-clk {\n" + "> +\t\tclock-frequency = <33333333>;\n" + "> +\t\tcompatible = \"fixed-clock\";\n" + "> +\t\t#clock-cells = <0>;\n" + "> +\t};\n" + "> +\n" + "> +\tcore-clk: core-clk@80 {\n" + "> +\t\tcompatible = \"snps,axs10x-arc-pll-clock\";\n" + "> +\t\treg = <0x80 0x10 0x100 0x10>;\n" + "> +\t\t#clock-cells = <0>;\n" + "> +\t\tclocks = <&input-clk>;\n" + "> +\t};\n" + "> diff --git a/MAINTAINERS b/MAINTAINERS\n" + "> index 3960e7f..5805833 100644\n" + "> --- a/MAINTAINERS\n" + "> +++ b/MAINTAINERS\n" + "> @@ -11910,6 +11910,12 @@ F:\tarch/arc/plat-axs10x\n" + "> \302\240F:\tarch/arc/boot/dts/ax*\n" + "> \302\240F:\tDocumentation/devicetree/bindings/arc/axs10*\n" + "> \302\240\n" + "> +SYNOPSYS ARC SDP clock driver\n" + "> +M:\tVlad Zakharov <vzakhar@synopsys.com>\n" + "> +S:\tSupported\n" + "> +F:\tdrivers/clk/axs10x/*\n" + "> +F:\tDocumentation/devicetree/bindings/clock/snps,pll-clock.txt\n" + "> +\n" + "> \302\240SYSTEM CONFIGURATION (SYSCON)\n" + "> \302\240M:\tLee Jones <lee.jones@linaro.org>\n" + "> \302\240M:\tArnd Bergmann <arnd@arndb.de>\n" + "> diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile\n" + "> index 01996b8..d747dea 100644\n" + "> --- a/drivers/clk/axs10x/Makefile\n" + "> +++ b/drivers/clk/axs10x/Makefile\n" + "> @@ -1 +1,2 @@\n" + "> \302\240obj-y += i2s_pll_clock.o\n" + "> +obj-y += pll_clock.o\n" + "> diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c\n" + "> new file mode 100644\n" + "> index 0000000..784a0a2\n" + "> --- /dev/null\n" + "> +++ b/drivers/clk/axs10x/pll_clock.c\n" + "> @@ -0,0 +1,384 @@\n" + "> +/*\n" + "> + * Synopsys AXS10X SDP Generic PLL clock driver\n" + "> + *\n" + "> + * Copyright (C) 2017 Synopsys\n" + "> + *\n" + "> + * This file is licensed under the terms of the GNU General Public\n" + "> + * License version 2. This program is licensed \"as is\" without any\n" + "> + * warranty of any kind, whether express or implied.\n" + "> + */\n" + "> +\n" + "> +#include <linux/platform_device.h>\n" + "> +#include <linux/module.h>\n" + "> +#include <linux/clk-provider.h>\n" + "> +#include <linux/delay.h>\n" + "> +#include <linux/err.h>\n" + "> +#include <linux/device.h>\n" + "> +#include <linux/of_address.h>\n" + "> +#include <linux/of_device.h>\n" + "> +#include <linux/slab.h>\n" + "> +#include <linux/of.h>\n" + "> +\n" + "> +/* PLL registers addresses */\n" + "> +#define PLL_REG_IDIV\t0x0\n" + "> +#define PLL_REG_FBDIV\t0x4\n" + "> +#define PLL_REG_ODIV\t0x8\n" + "> +\n" + "> +/*\n" + "> + * Bit fields of the PLL IDIV/FBDIV/ODIV registers:\n" + "> + *\302\240\302\240________________________________________________________________________\n" + "> + * |31\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\24015|\302\240\302\240\302\240\302\24014\302\240\302\240\302\240\302\240|\302\240\302\240\302\24013\302\240\302\240\302\240|\302\240\302\24012\302\240\302\240|11\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\2406|5\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\2400|\n" + "> + * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--|\n" + "> + * |____________________|__________|________|______|____________|___________|\n" + "> + *\n" + "> + * Following macros detirmine the way of access to these registers\n" + "> + * They should be set up only using the macros.\n" + "> + * reg should be and uint32_t variable.\n" + "> + */\n" + "> +\n" + "> +#define PLL_REG_GET_LOW(reg)\t\t\t\\\n" + "> +\t(((reg) & (0x3F << 0)) >> 0)\n" + "> +#define PLL_REG_GET_HIGH(reg)\t\t\t\\\n" + "> +\t(((reg) & (0x3F << 6)) >> 6)\n" + "> +#define PLL_REG_GET_EDGE(reg)\t\t\t\\\n" + "> +\t(((reg) & (BIT(12))) ? 1 : 0)\n" + "> +#define PLL_REG_GET_BYPASS(reg)\t\t\t\\\n" + "> +\t(((reg) & (BIT(13))) ? 1 : 0)\n" + "> +#define PLL_REG_GET_NOUPD(reg)\t\t\t\\\n" + "> +\t(((reg) & (BIT(14))) ? 1 : 0)\n" + "> +#define PLL_REG_GET_PAD(reg)\t\t\t\\\n" + "> +\t(((reg) & (0x1FFFF << 15)) >> 15)\n" + "> +\n" + "> +#define PLL_REG_SET_LOW(reg, value)\t\t\\\n" + "> +\t{ reg |= (((value) & 0x3F) << 0); }\n" + "> +#define PLL_REG_SET_HIGH(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x3F) << 6); }\n" + "> +#define PLL_REG_SET_EDGE(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x01) << 12); }\n" + "> +#define PLL_REG_SET_BYPASS(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x01) << 13); }\n" + "> +#define PLL_REG_SET_NOUPD(reg, value)\t\\\n" + "> +\t{ reg |= (((value) & 0x01) << 14); }\n" + "> +#define PLL_REG_SET_PAD(reg, value)\t\t\\\n" + "> +\t{ reg |= (((value) & 0x1FFFF) << 15); }\n" + "> +\n" + "> +#define PLL_LOCK\t0x1\n" + "> +#define PLL_MAX_LOCK_TIME 100 /* 100 us */\n" + "> +\n" + "> +struct pll_cfg {\n" + "> +\tu32 rate;\n" + "> +\tu32 idiv;\n" + "> +\tu32 fbdiv;\n" + "> +\tu32 odiv;\n" + "> +};\n" + "> +\n" + "> +struct pll_of_table {\n" + "> +\tunsigned long prate;\n" + "> +\tstruct pll_cfg *pll_cfg_table;\n" + "> +};\n" + "> +\n" + "> +struct pll_of_data {\n" + "> +\tstruct pll_of_table *pll_table;\n" + "> +};\n" + "> +\n" + "> +static struct pll_of_data pgu_pll_data = {\n" + "> +\t.pll_table = (struct pll_of_table []){\n" + "> +\t\t{\n" + "> +\t\t\t.prate = 27000000,\n" + "> +\t\t\t.pll_cfg_table = (struct pll_cfg []){\n" + "> +\t\t\t\t{ 25200000, 1, 84, 90 },\n" + "> +\t\t\t\t{ 50000000, 1, 100, 54 },\n" + "> +\t\t\t\t{ 74250000, 1, 44, 16 },\n" + "> +\t\t\t\t{ },\n" + "> +\t\t\t},\n" + "> +\t\t},\n" + "> +\t\t/* Used as list limiter */\n" + "> +\t\t{ },\n" + "> +\t},\n" + "> +};\n" + "> +\n" + "> +static struct pll_of_data arc_pll_data = {\n" + "> +\t.pll_table = (struct pll_of_table []){\n" + "> +\t\t{\n" + "> +\t\t\t.prate = 33333333,\n" + "> +\t\t\t.pll_cfg_table = (struct pll_cfg []){\n" + "> +\t\t\t\t{ 33333333,\302\240\302\2401, 1,\302\240\302\2401 },\n" + "> +\t\t\t\t{ 50000000,\302\240\302\2401, 30, 20 },\n" + "> +\t\t\t\t{ 75000000,\302\240\302\2402, 45, 10 },\n" + "> +\t\t\t\t{ 90000000,\302\240\302\2402, 54, 10 },\n" + "> +\t\t\t\t{ 100000000, 1, 30, 10 },\n" + "> +\t\t\t\t{ 125000000, 2, 45, 6 },\n" + "> +\t\t\t\t{ },\n" + "> +\t\t\t},\n" + "> +\t\t},\n" + "> +\t\t/* Used as list limiter */\n" + "> +\t\t{ },\n" + "> +\t},\n" + "> +};\n" + "> +\n" + "> +struct pll_clk {\n" + "> +\tvoid __iomem *base;\n" + "> +\tvoid __iomem *lock;\n" + "> +\tconst struct pll_of_data *pll_data;\n" + "> +\tstruct clk_hw hw;\n" + "> +\tstruct device *dev;\n" + "> +};\n" + "> +\n" + "> +static inline void pll_write(struct pll_clk *clk, unsigned int reg,\n" + "> +\t\tunsigned int val)\n" + "> +{\n" + "> +\tiowrite32(val, clk->base + reg);\n" + "> +}\n" + "> +\n" + "> +static inline u32 pll_read(struct pll_clk *clk,\n" + "> +\t\tunsigned int reg)\n" + "> +{\n" + "> +\treturn ioread32(clk->base + reg);\n" + "> +}\n" + "> +\n" + "> +static inline struct pll_clk *to_pll_clk(struct clk_hw *hw)\n" + "> +{\n" + "> +\treturn container_of(hw, struct pll_clk, hw);\n" + "> +}\n" + "> +\n" + "> +static inline u32 div_get_value(unsigned int reg)\n" + "> +{\n" + "> +\tif (PLL_REG_GET_BYPASS(reg))\n" + "> +\t\treturn 1;\n" + "> +\n" + "> +\treturn (PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg));\n" + "> +}\n" + "> +\n" + "> +static inline u32 encode_div(unsigned int id, int upd)\n" + "> +{\n" + "> +\tuint32_t div = 0;\n" + "> +\n" + "> +\tPLL_REG_SET_LOW(div, (id%2 == 0) ? id >> 1 : (id >> 1) + 1);\n" + "> +\tPLL_REG_SET_HIGH(div, id >> 1);\n" + "> +\tPLL_REG_SET_EDGE(div, id%2);\n" + "> +\tPLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0);\n" + "> +\tPLL_REG_SET_NOUPD(div, !upd);\n" + "> +\n" + "> +\treturn div;\n" + "> +}\n" + "> +\n" + "> +static const struct pll_cfg *pll_get_cfg(unsigned long prate,\n" + "> +\t\tconst struct pll_of_table *pll_table)\n" + "> +{\n" + "> +\tint i;\n" + "> +\n" + "> +\tfor (i = 0; pll_table[i].prate != 0; i++)\n" + "> +\t\tif (pll_table[i].prate == prate)\n" + "> +\t\t\treturn pll_table[i].pll_cfg_table;\n" + "> +\n" + "> +\treturn NULL;\n" + "> +}\n" + "> +\n" + "> +static unsigned long pll_recalc_rate(struct clk_hw *hw,\n" + "> +\t\t\tunsigned long parent_rate)\n" + "> +{\n" + "> +\tu64 rate;\n" + "> +\tu32 idiv, fbdiv, odiv;\n" + "> +\tstruct pll_clk *clk = to_pll_clk(hw);\n" + "> +\n" + "> +\tidiv = div_get_value(pll_read(clk, PLL_REG_IDIV));\n" + "> +\tfbdiv = div_get_value(pll_read(clk, PLL_REG_FBDIV));\n" + "> +\todiv = div_get_value(pll_read(clk, PLL_REG_ODIV));\n" + "> +\n" + "> +\trate = (u64)parent_rate * fbdiv;\n" + "> +\tdo_div(rate, idiv * odiv);\n" + "> +\n" + "> +\treturn (unsigned long)rate;\n" + "> +}\n" + "> +\n" + "> +static long pll_round_rate(struct clk_hw *hw, unsigned long rate,\n" + "> +\t\t\tunsigned long *prate)\n" + "> +{\n" + "> +\tint i;\n" + "> +\tlong best_rate;\n" + "> +\tstruct pll_clk *clk = to_pll_clk(hw);\n" + "> +\tconst struct pll_cfg *pll_cfg = pll_get_cfg(*prate,\n" + "> +\t\t\tclk->pll_data->pll_table);\n" + "> +\n" + "> +\tif (!pll_cfg) {\n" + "> +\t\tdev_err(clk->dev, \"invalid parent rate=%ld\\n\", *prate);\n" + "> +\t\treturn -EINVAL;\n" + "> +\t}\n" + "> +\n" + "> +\tif (pll_cfg[0].rate == 0)\n" + "> +\t\treturn -EINVAL;\n" + "> +\n" + "> +\tbest_rate = pll_cfg[0].rate;\n" + "> +\n" + "> +\tfor (i = 1; pll_cfg[i].rate != 0; i++) {\n" + "> +\t\tif (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate))\n" + "> +\t\t\tbest_rate = pll_cfg[i].rate;\n" + "> +\t}\n" + "> +\n" + "> +\treturn best_rate;\n" + "> +}\n" + "> +\n" + "> +static int pll_set_rate(struct clk_hw *hw, unsigned long rate,\n" + "> +\t\t\tunsigned long parent_rate)\n" + "> +{\n" + "> +\tint i;\n" + "> +\tstruct pll_clk *clk = to_pll_clk(hw);\n" + "> +\tconst struct pll_cfg *pll_cfg = pll_get_cfg(parent_rate,\n" + "> +\t\t\tclk->pll_data->pll_table);\n" + "> +\n" + "> +\tif (!pll_cfg) {\n" + "> +\t\tdev_err(clk->dev, \"invalid parent rate=%ld\\n\", parent_rate);\n" + "> +\t\treturn -EINVAL;\n" + "> +\t}\n" + "> +\n" + "> +\tfor (i = 0; pll_cfg[i].rate != 0; i++) {\n" + "> +\t\tif (pll_cfg[i].rate == rate) {\n" + "> +\t\t\tpll_write(clk, PLL_REG_IDIV,\n" + "> +\t\t\t\t\tencode_div(pll_cfg[i].idiv, 0));\n" + "> +\t\t\tpll_write(clk, PLL_REG_FBDIV,\n" + "> +\t\t\t\t\tencode_div(pll_cfg[i].fbdiv, 0));\n" + "> +\t\t\tpll_write(clk, PLL_REG_ODIV,\n" + "> +\t\t\t\t\tencode_div(pll_cfg[i].odiv, 1));\n" + "> +\n" + "> +\t\t\t/*\n" + "> +\t\t\t\302\240* Wait until CGU relocks.\n" + "> +\t\t\t\302\240* If after timeout CGU is unlocked yet return error\n" + "> +\t\t\t\302\240*/\n" + "> +\t\t\tudelay(PLL_MAX_LOCK_TIME);\n" + "> +\t\t\tif (ioread32(clk->lock) & PLL_LOCK)\n" + "> +\t\t\t\treturn 0;\n" + "> +\t\t\telse\n" + "> +\t\t\t\treturn -ETIMEDOUT;\n" + "> +\t\t}\n" + "> +\t}\n" + "> +\n" + "> +\tdev_err(clk->dev, \"invalid rate=%ld, parent_rate=%ld\\n\", rate,\n" + "> +\t\t\tparent_rate);\n" + "> +\treturn -EINVAL;\n" + "> +}\n" + "> +\n" + "> +static const struct clk_ops pll_ops = {\n" + "> +\t.recalc_rate = pll_recalc_rate,\n" + "> +\t.round_rate = pll_round_rate,\n" + "> +\t.set_rate = pll_set_rate,\n" + "> +};\n" + "> +\n" + "> +static int pll_clk_probe(struct platform_device *pdev)\n" + "> +{\n" + "> +\tstruct device *dev = &pdev->dev;\n" + "> +\tconst char *parent_name;\n" + "> +\tstruct clk *clk;\n" + "> +\tstruct pll_clk *pll_clk;\n" + "> +\tstruct resource *mem;\n" + "> +\tstruct clk_init_data init = { };\n" + "> +\n" + "> +\tpll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);\n" + "> +\tif (!pll_clk)\n" + "> +\t\treturn -ENOMEM;\n" + "> +\n" + "> +\tmem = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n" + "> +\tpll_clk->base = devm_ioremap_resource(dev, mem);\n" + "> +\tif (IS_ERR(pll_clk->base))\n" + "> +\t\treturn PTR_ERR(pll_clk->base);\n" + "> +\n" + "> +\tmem = platform_get_resource(pdev, IORESOURCE_MEM, 1);\n" + "> +\tpll_clk->lock = devm_ioremap_resource(dev, mem);\n" + "> +\tif (IS_ERR(pll_clk->lock))\n" + "> +\t\treturn PTR_ERR(pll_clk->base);\n" + "> +\n" + "> +\tinit.name = dev->of_node->name;\n" + "> +\tinit.ops = &pll_ops;\n" + "> +\tparent_name = of_clk_get_parent_name(dev->of_node, 0);\n" + "> +\tinit.parent_names = &parent_name;\n" + "> +\tinit.num_parents = 1;\n" + "> +\tpll_clk->hw.init = &init;\n" + "> +\tpll_clk->dev = dev;\n" + "> +\tpll_clk->pll_data = of_device_get_match_data(dev);\n" + "> +\n" + "> +\tif (!pll_clk->pll_data) {\n" + "> +\t\tdev_err(dev, \"No OF match data provided\\n\");\n" + "> +\t\t\treturn -EINVAL;\n" + "> +\t}\n" + "> +\n" + "> +\tclk = devm_clk_register(dev, &pll_clk->hw);\n" + "> +\tif (IS_ERR(clk)) {\n" + "> +\t\tdev_err(dev, \"failed to register %s clock (%ld)\\n\",\n" + "> +\t\t\t\tinit.name, PTR_ERR(clk));\n" + "> +\t\treturn PTR_ERR(clk);\n" + "> +\t}\n" + "> +\n" + "> +\treturn of_clk_add_provider(dev->of_node, of_clk_src_simple_get, clk);\n" + "> +}\n" + "> +\n" + "> +static int pll_clk_remove(struct platform_device *pdev)\n" + "> +{\n" + "> +\tof_clk_del_provider(pdev->dev.of_node);\n" + "> +\treturn 0;\n" + "> +}\n" + "> +\n" + "> +static void __init of_pll_clk_setup(struct device_node *node)\n" + "> +{\n" + "> +\tconst char *parent_name;\n" + "> +\tstruct clk *clk;\n" + "> +\tstruct pll_clk *pll_clk;\n" + "> +\tstruct clk_init_data init = { };\n" + "> +\n" + "> +\tpll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);\n" + "> +\tif (!pll_clk)\n" + "> +\t\treturn;\n" + "> +\n" + "> +\tpll_clk->base = of_iomap(node, 0);\n" + "> +\tif (!pll_clk->base) {\n" + "> +\t\tpr_err(\"failed to map pll div registers\\n\");\n" + "> +\t\tiounmap(pll_clk->base);\n" + "> +\t\treturn;\n" + "> +\t}\n" + "> +\n" + "> +\tpll_clk->lock = of_iomap(node, 1);\n" + "> +\tif (!pll_clk->lock) {\n" + "> +\t\tpr_err(\"failed to map pll lock register\\n\");\n" + "> +\t\tiounmap(pll_clk->lock);\n" + "> +\t\treturn;\n" + "> +\t}\n" + "> +\n" + "> +\tinit.name = node->name;\n" + "> +\tinit.ops = &pll_ops;\n" + "> +\tparent_name = of_clk_get_parent_name(node, 0);\n" + "> +\tinit.parent_names = &parent_name;\n" + "> +\tinit.num_parents = parent_name ? 1 : 0;\n" + "> +\tpll_clk->hw.init = &init;\n" + "> +\tpll_clk->pll_data = &arc_pll_data;\n" + "> +\n" + "> +\tclk = clk_register(NULL, &pll_clk->hw);\n" + "> +\tif (IS_ERR(clk)) {\n" + "> +\t\tpr_err(\"failed to register %s clock (%ld)\\n\",\n" + "> +\t\t\t\tnode->name, PTR_ERR(clk));\n" + "> +\t\tkfree(pll_clk);\n" + "> +\t\treturn;\n" + "> +\t}\n" + "> +\n" + "> +\tof_clk_add_provider(node, of_clk_src_simple_get, clk);\n" + "> +}\n" + "> +\n" + "> +CLK_OF_DECLARE(axs10x_pll_clock, \"snps,axs10x-arc-pll-clock\", of_pll_clk_setup);\n" + "> +\n" + "> +static const struct of_device_id pll_clk_id[] = {\n" + "> +\t{ .compatible = \"snps,axs10x-arc-pll-clock\", .data = &arc_pll_data},\n" + "> +\t{ .compatible = \"snps,axs10x-pgu-pll-clock\", .data = &pgu_pll_data},\n" + "> +\t{ },\n" + "> +};\n" + "> +MODULE_DEVICE_TABLE(of, pll_clk_id);\n" + "> +\n" + "> +static struct platform_driver pll_clk_driver = {\n" + "> +\t.driver = {\n" + "> +\t\t.name = \"axs10x-pll-clock\",\n" + "> +\t\t.of_match_table = pll_clk_id,\n" + "> +\t},\n" + "> +\t.probe = pll_clk_probe,\n" + "> +\t.remove = pll_clk_remove,\n" + "> +};\n" + "> +builtin_platform_driver(pll_clk_driver);\n" + "> +\n" + "> +MODULE_AUTHOR(\"Vlad Zakharov <vzakhar@synopsys.com>\");\n" + "> +MODULE_DESCRIPTION(\"Synopsys AXS10X SDP Generic PLL Clock Driver\");\n" + "> +MODULE_LICENSE(\"GPL v2\");\n" + "\n" + "Maybe you have any comments or remarks about this patch? And if you don't could you please apply it.\n" + "\n" + "Thanks!\n" + "\n" + "-- \n" + "Best regards,\n" + Vlad Zakharov <vzakhar@synopsys.com> -36fae7fa84d07b8086c925e623f6ba88940d662237db2b05d1e273fbce8d0b15 +d747ccbc87f6c0f9f3a23b80e26e4c973a08d1398feb88e5eb7c7d13357e2150
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.