From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757472AbdELLB3 (ORCPT ); Fri, 12 May 2017 07:01:29 -0400 Received: from smtp.domeneshop.no ([194.63.252.55]:51817 "EHLO smtp.domeneshop.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756449AbdELLB1 (ORCPT ); Fri, 12 May 2017 07:01:27 -0400 Subject: Re: [PATCH 1/4] drm/vc4: Adjust modes in DSI to work around the integer PLL divider. To: Eric Anholt , dri-devel@lists.freedesktop.org, Thierry Reding , Rob Herring , Mark Rutland , Archit Taneja , Andrzej Hajda , Laurent Pinchart , devicetree@vger.kernel.org References: <20170511235625.22427-1-eric@anholt.net> <20170511235625.22427-2-eric@anholt.net> Cc: linux-kernel@vger.kernel.org From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Message-ID: <3622e7b6-8ab0-38b9-fc2a-9949a93b6111@tronnes.org> Date: Fri, 12 May 2017 13:01:19 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <20170511235625.22427-2-eric@anholt.net> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Den 12.05.2017 01.56, skrev Eric Anholt: > BCM2835's PLLD_DSI1 divider doesn't give us many choices for our pixel > clocks, so to support panels on the Raspberry Pi we need to set a > higher pixel clock rate than requested and adjust the mode we program > to extend out the HFP so that the refresh rate matches. > > Signed-off-by: Eric Anholt > --- > drivers/gpu/drm/vc4/vc4_dsi.c | 112 ++++++++++++++++++++++++++++++++---------- > 1 file changed, 86 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c > index fb54a9d10360..62cb3b0d0345 100644 > --- a/drivers/gpu/drm/vc4/vc4_dsi.c > +++ b/drivers/gpu/drm/vc4/vc4_dsi.c > @@ -519,7 +519,8 @@ struct vc4_dsi { > /* DSI channel for the panel we're connected to. */ > u32 channel; > u32 lanes; > - enum mipi_dsi_pixel_format format; > + u32 format; > + u32 divider; > u32 mode_flags; > > /* Input clock from CPRMAN to the digital PHY, for the DSI > @@ -817,13 +818,67 @@ static void vc4_dsi_encoder_disable(struct drm_encoder *encoder) > pm_runtime_put(dev); > } > > +/* Extends the mode's blank intervals to handle BCM2835's integer-only > + * DSI PLL divider. > + * > + * On 2835, PLLD is set to 2Ghz, and may not be changed by the display > + * driver since most peripherals are hanging off of the PLLD_PER > + * divider. PLLD_DSI1, which drives our DSI bit clock (and therefore > + * the pixel clock), only has an integer divider off of DSI. > + * > + * To get our panel mode to refresh at the expected 60Hz, we need to > + * extend the horizontal blank time. This means we drive a > + * higher-than-expected clock rate to the panel, but that's what the > + * firmware (which ) does too. Something missing in the comment here. Noralf. > + */ > +static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder, > + const struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > +{ > + struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder); > + struct vc4_dsi *dsi = vc4_encoder->dsi; > + struct clk *phy_parent = clk_get_parent(dsi->pll_phy_clock); > + unsigned long parent_rate = clk_get_rate(phy_parent); > + unsigned long pixel_clock_hz = mode->clock * 1000; > + unsigned long pll_clock = pixel_clock_hz * dsi->divider; > + int divider; > + > + /* Find what divider gets us a faster clock than the requested > + * pixel clock. > + */ > + for (divider = 1; divider < 8; divider++) { > + if (parent_rate / divider < pll_clock) { > + divider--; > + break; > + } > + } > + > + /* Now that we've picked a PLL divider, calculate back to its > + * pixel clock. > + */ > + pll_clock = parent_rate / divider; > + pixel_clock_hz = pll_clock / dsi->divider; > + > + /* Round up the clk_set_rate() request slightly, since > + * PLLD_DSI1 is an integer divider and its rate selection will > + * never round up. > + */ > + adjusted_mode->clock = pixel_clock_hz / 1000 + 1; > + > + /* Given the new pixel clock, adjust HFP to keep vrefresh the same. */ > + adjusted_mode->htotal = pixel_clock_hz / (mode->vrefresh * mode->vtotal); > + adjusted_mode->hsync_end += adjusted_mode->htotal - mode->htotal; > + adjusted_mode->hsync_start += adjusted_mode->htotal - mode->htotal; > + > + return true; > +} > + > static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) > { > - struct drm_display_mode *mode = &encoder->crtc->mode; > + struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; > struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder); > struct vc4_dsi *dsi = vc4_encoder->dsi; > struct device *dev = &dsi->pdev->dev; > - u32 format = 0, divider = 0; > bool debug_dump_regs = false; > unsigned long hs_clock; > u32 ui_ns; > @@ -845,26 +900,7 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) > vc4_dsi_dump_regs(dsi); > } > > - switch (dsi->format) { > - case MIPI_DSI_FMT_RGB888: > - format = DSI_PFORMAT_RGB888; > - divider = 24 / dsi->lanes; > - break; > - case MIPI_DSI_FMT_RGB666: > - format = DSI_PFORMAT_RGB666; > - divider = 24 / dsi->lanes; > - break; > - case MIPI_DSI_FMT_RGB666_PACKED: > - format = DSI_PFORMAT_RGB666_PACKED; > - divider = 18 / dsi->lanes; > - break; > - case MIPI_DSI_FMT_RGB565: > - format = DSI_PFORMAT_RGB565; > - divider = 16 / dsi->lanes; > - break; > - } > - > - phy_clock = pixel_clock_hz * divider; > + phy_clock = pixel_clock_hz * dsi->divider; > ret = clk_set_rate(dsi->pll_phy_clock, phy_clock); > if (ret) { > dev_err(&dsi->pdev->dev, > @@ -1049,8 +1085,9 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) > > if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { > DSI_PORT_WRITE(DISP0_CTRL, > - VC4_SET_FIELD(divider, DSI_DISP0_PIX_CLK_DIV) | > - VC4_SET_FIELD(format, DSI_DISP0_PFORMAT) | > + VC4_SET_FIELD(dsi->divider, > + DSI_DISP0_PIX_CLK_DIV) | > + VC4_SET_FIELD(dsi->format, DSI_DISP0_PFORMAT) | > VC4_SET_FIELD(DSI_DISP0_LP_STOP_PERFRAME, > DSI_DISP0_LP_STOP_CTRL) | > DSI_DISP0_ST_END | > @@ -1255,9 +1292,31 @@ static int vc4_dsi_host_attach(struct mipi_dsi_host *host, > > dsi->lanes = device->lanes; > dsi->channel = device->channel; > - dsi->format = device->format; > dsi->mode_flags = device->mode_flags; > > + switch (device->format) { > + case MIPI_DSI_FMT_RGB888: > + dsi->format = DSI_PFORMAT_RGB888; > + dsi->divider = 24 / dsi->lanes; > + break; > + case MIPI_DSI_FMT_RGB666: > + dsi->format = DSI_PFORMAT_RGB666; > + dsi->divider = 24 / dsi->lanes; > + break; > + case MIPI_DSI_FMT_RGB666_PACKED: > + dsi->format = DSI_PFORMAT_RGB666_PACKED; > + dsi->divider = 18 / dsi->lanes; > + break; > + case MIPI_DSI_FMT_RGB565: > + dsi->format = DSI_PFORMAT_RGB565; > + dsi->divider = 16 / dsi->lanes; > + break; > + default: > + dev_err(&dsi->pdev->dev, "Unknown DSI format: %d.\n", > + dsi->format); > + return 0; > + } > + > if (!(dsi->mode_flags & MIPI_DSI_MODE_VIDEO)) { > dev_err(&dsi->pdev->dev, > "Only VIDEO mode panels supported currently.\n"); > @@ -1304,6 +1363,7 @@ static const struct mipi_dsi_host_ops vc4_dsi_host_ops = { > static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = { > .disable = vc4_dsi_encoder_disable, > .enable = vc4_dsi_encoder_enable, > + .mode_fixup = vc4_dsi_encoder_mode_fixup, > }; > > static const struct of_device_id vc4_dsi_dt_match[] = { From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Subject: Re: [PATCH 1/4] drm/vc4: Adjust modes in DSI to work around the integer PLL divider. Date: Fri, 12 May 2017 13:01:19 +0200 Message-ID: <3622e7b6-8ab0-38b9-fc2a-9949a93b6111@tronnes.org> References: <20170511235625.22427-1-eric@anholt.net> <20170511235625.22427-2-eric@anholt.net> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20170511235625.22427-2-eric@anholt.net> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Eric Anholt , dri-devel@lists.freedesktop.org, Thierry Reding , Rob Herring , Mark Rutland , Archit Taneja , Andrzej Hajda , Laurent Pinchart , devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org List-Id: devicetree@vger.kernel.org CkRlbiAxMi4wNS4yMDE3IDAxLjU2LCBza3JldiBFcmljIEFuaG9sdDoKPiBCQ00yODM1J3MgUExM RF9EU0kxIGRpdmlkZXIgZG9lc24ndCBnaXZlIHVzIG1hbnkgY2hvaWNlcyBmb3Igb3VyIHBpeGVs Cj4gY2xvY2tzLCBzbyB0byBzdXBwb3J0IHBhbmVscyBvbiB0aGUgUmFzcGJlcnJ5IFBpIHdlIG5l ZWQgdG8gc2V0IGEKPiBoaWdoZXIgcGl4ZWwgY2xvY2sgcmF0ZSB0aGFuIHJlcXVlc3RlZCBhbmQg YWRqdXN0IHRoZSBtb2RlIHdlIHByb2dyYW0KPiB0byBleHRlbmQgb3V0IHRoZSBIRlAgc28gdGhh dCB0aGUgcmVmcmVzaCByYXRlIG1hdGNoZXMuCj4KPiBTaWduZWQtb2ZmLWJ5OiBFcmljIEFuaG9s dCA8ZXJpY0BhbmhvbHQubmV0Pgo+IC0tLQo+ICAgZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfZHNp LmMgfCAxMTIgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKystLS0tLS0tLS0tCj4gICAx IGZpbGUgY2hhbmdlZCwgODYgaW5zZXJ0aW9ucygrKSwgMjYgZGVsZXRpb25zKC0pCj4KPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfZHNpLmMgYi9kcml2ZXJzL2dwdS9kcm0v dmM0L3ZjNF9kc2kuYwo+IGluZGV4IGZiNTRhOWQxMDM2MC4uNjJjYjNiMGQwMzQ1IDEwMDY0NAo+ IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS92YzQvdmM0X2RzaS5jCj4gKysrIGIvZHJpdmVycy9ncHUv ZHJtL3ZjNC92YzRfZHNpLmMKPiBAQCAtNTE5LDcgKzUxOSw4IEBAIHN0cnVjdCB2YzRfZHNpIHsK PiAgIAkvKiBEU0kgY2hhbm5lbCBmb3IgdGhlIHBhbmVsIHdlJ3JlIGNvbm5lY3RlZCB0by4gKi8K PiAgIAl1MzIgY2hhbm5lbDsKPiAgIAl1MzIgbGFuZXM7Cj4gLQllbnVtIG1pcGlfZHNpX3BpeGVs X2Zvcm1hdCBmb3JtYXQ7Cj4gKwl1MzIgZm9ybWF0Owo+ICsJdTMyIGRpdmlkZXI7Cj4gICAJdTMy IG1vZGVfZmxhZ3M7Cj4gICAKPiAgIAkvKiBJbnB1dCBjbG9jayBmcm9tIENQUk1BTiB0byB0aGUg ZGlnaXRhbCBQSFksIGZvciB0aGUgRFNJCj4gQEAgLTgxNywxMyArODE4LDY3IEBAIHN0YXRpYyB2 b2lkIHZjNF9kc2lfZW5jb2Rlcl9kaXNhYmxlKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlcikK PiAgIAlwbV9ydW50aW1lX3B1dChkZXYpOwo+ICAgfQo+ICAgCj4gKy8qIEV4dGVuZHMgdGhlIG1v ZGUncyBibGFuayBpbnRlcnZhbHMgdG8gaGFuZGxlIEJDTTI4MzUncyBpbnRlZ2VyLW9ubHkKPiAr ICogRFNJIFBMTCBkaXZpZGVyLgo+ICsgKgo+ICsgKiBPbiAyODM1LCBQTExEIGlzIHNldCB0byAy R2h6LCBhbmQgbWF5IG5vdCBiZSBjaGFuZ2VkIGJ5IHRoZSBkaXNwbGF5Cj4gKyAqIGRyaXZlciBz aW5jZSBtb3N0IHBlcmlwaGVyYWxzIGFyZSBoYW5naW5nIG9mZiBvZiB0aGUgUExMRF9QRVIKPiAr ICogZGl2aWRlci4gIFBMTERfRFNJMSwgd2hpY2ggZHJpdmVzIG91ciBEU0kgYml0IGNsb2NrIChh bmQgdGhlcmVmb3JlCj4gKyAqIHRoZSBwaXhlbCBjbG9jayksIG9ubHkgaGFzIGFuIGludGVnZXIg ZGl2aWRlciBvZmYgb2YgRFNJLgo+ICsgKgo+ICsgKiBUbyBnZXQgb3VyIHBhbmVsIG1vZGUgdG8g cmVmcmVzaCBhdCB0aGUgZXhwZWN0ZWQgNjBIeiwgd2UgbmVlZCB0bwo+ICsgKiBleHRlbmQgdGhl IGhvcml6b250YWwgYmxhbmsgdGltZS4gIFRoaXMgbWVhbnMgd2UgZHJpdmUgYQo+ICsgKiBoaWdo ZXItdGhhbi1leHBlY3RlZCBjbG9jayByYXRlIHRvIHRoZSBwYW5lbCwgYnV0IHRoYXQncyB3aGF0 IHRoZQo+ICsgKiBmaXJtd2FyZSAod2hpY2ggKSBkb2VzIHRvby4KClNvbWV0aGluZyBtaXNzaW5n IGluIHRoZSBjb21tZW50IGhlcmUuCgpOb3JhbGYuCgo+ICsgKi8KPiArc3RhdGljIGJvb2wgdmM0 X2RzaV9lbmNvZGVyX21vZGVfZml4dXAoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyLAo+ICsJ CQkJICAgICAgIGNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlLAo+ICsJCQkJICAg ICAgIHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICphZGp1c3RlZF9tb2RlKQo+ICt7Cj4gKwlzdHJ1 Y3QgdmM0X2RzaV9lbmNvZGVyICp2YzRfZW5jb2RlciA9IHRvX3ZjNF9kc2lfZW5jb2RlcihlbmNv ZGVyKTsKPiArCXN0cnVjdCB2YzRfZHNpICpkc2kgPSB2YzRfZW5jb2Rlci0+ZHNpOwo+ICsJc3Ry dWN0IGNsayAqcGh5X3BhcmVudCA9IGNsa19nZXRfcGFyZW50KGRzaS0+cGxsX3BoeV9jbG9jayk7 Cj4gKwl1bnNpZ25lZCBsb25nIHBhcmVudF9yYXRlID0gY2xrX2dldF9yYXRlKHBoeV9wYXJlbnQp Owo+ICsJdW5zaWduZWQgbG9uZyBwaXhlbF9jbG9ja19oeiA9IG1vZGUtPmNsb2NrICogMTAwMDsK PiArCXVuc2lnbmVkIGxvbmcgcGxsX2Nsb2NrID0gcGl4ZWxfY2xvY2tfaHogKiBkc2ktPmRpdmlk ZXI7Cj4gKwlpbnQgZGl2aWRlcjsKPiArCj4gKwkvKiBGaW5kIHdoYXQgZGl2aWRlciBnZXRzIHVz IGEgZmFzdGVyIGNsb2NrIHRoYW4gdGhlIHJlcXVlc3RlZAo+ICsJICogcGl4ZWwgY2xvY2suCj4g KwkgKi8KPiArCWZvciAoZGl2aWRlciA9IDE7IGRpdmlkZXIgPCA4OyBkaXZpZGVyKyspIHsKPiAr CQlpZiAocGFyZW50X3JhdGUgLyBkaXZpZGVyIDwgcGxsX2Nsb2NrKSB7Cj4gKwkJCWRpdmlkZXIt LTsKPiArCQkJYnJlYWs7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCS8qIE5vdyB0aGF0IHdlJ3ZlIHBp Y2tlZCBhIFBMTCBkaXZpZGVyLCBjYWxjdWxhdGUgYmFjayB0byBpdHMKPiArCSAqIHBpeGVsIGNs b2NrLgo+ICsJICovCj4gKwlwbGxfY2xvY2sgPSBwYXJlbnRfcmF0ZSAvIGRpdmlkZXI7Cj4gKwlw aXhlbF9jbG9ja19oeiA9IHBsbF9jbG9jayAvIGRzaS0+ZGl2aWRlcjsKPiArCj4gKwkvKiBSb3Vu ZCB1cCB0aGUgY2xrX3NldF9yYXRlKCkgcmVxdWVzdCBzbGlnaHRseSwgc2luY2UKPiArCSAqIFBM TERfRFNJMSBpcyBhbiBpbnRlZ2VyIGRpdmlkZXIgYW5kIGl0cyByYXRlIHNlbGVjdGlvbiB3aWxs Cj4gKwkgKiBuZXZlciByb3VuZCB1cC4KPiArCSAqLwo+ICsJYWRqdXN0ZWRfbW9kZS0+Y2xvY2sg PSBwaXhlbF9jbG9ja19oeiAvIDEwMDAgKyAxOwo+ICsKPiArCS8qIEdpdmVuIHRoZSBuZXcgcGl4 ZWwgY2xvY2ssIGFkanVzdCBIRlAgdG8ga2VlcCB2cmVmcmVzaCB0aGUgc2FtZS4gKi8KPiArCWFk anVzdGVkX21vZGUtPmh0b3RhbCA9IHBpeGVsX2Nsb2NrX2h6IC8gKG1vZGUtPnZyZWZyZXNoICog bW9kZS0+dnRvdGFsKTsKPiArCWFkanVzdGVkX21vZGUtPmhzeW5jX2VuZCArPSBhZGp1c3RlZF9t b2RlLT5odG90YWwgLSBtb2RlLT5odG90YWw7Cj4gKwlhZGp1c3RlZF9tb2RlLT5oc3luY19zdGFy dCArPSBhZGp1c3RlZF9tb2RlLT5odG90YWwgLSBtb2RlLT5odG90YWw7Cj4gKwo+ICsJcmV0dXJu IHRydWU7Cj4gK30KPiArCj4gICBzdGF0aWMgdm9pZCB2YzRfZHNpX2VuY29kZXJfZW5hYmxlKHN0 cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlcikKPiAgIHsKPiAtCXN0cnVjdCBkcm1fZGlzcGxheV9t b2RlICptb2RlID0gJmVuY29kZXItPmNydGMtPm1vZGU7Cj4gKwlzdHJ1Y3QgZHJtX2Rpc3BsYXlf bW9kZSAqbW9kZSA9ICZlbmNvZGVyLT5jcnRjLT5zdGF0ZS0+YWRqdXN0ZWRfbW9kZTsKPiAgIAlz dHJ1Y3QgdmM0X2RzaV9lbmNvZGVyICp2YzRfZW5jb2RlciA9IHRvX3ZjNF9kc2lfZW5jb2Rlcihl bmNvZGVyKTsKPiAgIAlzdHJ1Y3QgdmM0X2RzaSAqZHNpID0gdmM0X2VuY29kZXItPmRzaTsKPiAg IAlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmZHNpLT5wZGV2LT5kZXY7Cj4gLQl1MzIgZm9ybWF0ID0g MCwgZGl2aWRlciA9IDA7Cj4gICAJYm9vbCBkZWJ1Z19kdW1wX3JlZ3MgPSBmYWxzZTsKPiAgIAl1 bnNpZ25lZCBsb25nIGhzX2Nsb2NrOwo+ICAgCXUzMiB1aV9uczsKPiBAQCAtODQ1LDI2ICs5MDAs NyBAQCBzdGF0aWMgdm9pZCB2YzRfZHNpX2VuY29kZXJfZW5hYmxlKHN0cnVjdCBkcm1fZW5jb2Rl ciAqZW5jb2RlcikKPiAgIAkJdmM0X2RzaV9kdW1wX3JlZ3MoZHNpKTsKPiAgIAl9Cj4gICAKPiAt CXN3aXRjaCAoZHNpLT5mb3JtYXQpIHsKPiAtCWNhc2UgTUlQSV9EU0lfRk1UX1JHQjg4ODoKPiAt CQlmb3JtYXQgPSBEU0lfUEZPUk1BVF9SR0I4ODg7Cj4gLQkJZGl2aWRlciA9IDI0IC8gZHNpLT5s YW5lczsKPiAtCQlicmVhazsKPiAtCWNhc2UgTUlQSV9EU0lfRk1UX1JHQjY2NjoKPiAtCQlmb3Jt YXQgPSBEU0lfUEZPUk1BVF9SR0I2NjY7Cj4gLQkJZGl2aWRlciA9IDI0IC8gZHNpLT5sYW5lczsK PiAtCQlicmVhazsKPiAtCWNhc2UgTUlQSV9EU0lfRk1UX1JHQjY2Nl9QQUNLRUQ6Cj4gLQkJZm9y bWF0ID0gRFNJX1BGT1JNQVRfUkdCNjY2X1BBQ0tFRDsKPiAtCQlkaXZpZGVyID0gMTggLyBkc2kt PmxhbmVzOwo+IC0JCWJyZWFrOwo+IC0JY2FzZSBNSVBJX0RTSV9GTVRfUkdCNTY1Ogo+IC0JCWZv cm1hdCA9IERTSV9QRk9STUFUX1JHQjU2NTsKPiAtCQlkaXZpZGVyID0gMTYgLyBkc2ktPmxhbmVz Owo+IC0JCWJyZWFrOwo+IC0JfQo+IC0KPiAtCXBoeV9jbG9jayA9IHBpeGVsX2Nsb2NrX2h6ICog ZGl2aWRlcjsKPiArCXBoeV9jbG9jayA9IHBpeGVsX2Nsb2NrX2h6ICogZHNpLT5kaXZpZGVyOwo+ ICAgCXJldCA9IGNsa19zZXRfcmF0ZShkc2ktPnBsbF9waHlfY2xvY2ssIHBoeV9jbG9jayk7Cj4g ICAJaWYgKHJldCkgewo+ICAgCQlkZXZfZXJyKCZkc2ktPnBkZXYtPmRldiwKPiBAQCAtMTA0OSw4 ICsxMDg1LDkgQEAgc3RhdGljIHZvaWQgdmM0X2RzaV9lbmNvZGVyX2VuYWJsZShzdHJ1Y3QgZHJt X2VuY29kZXIgKmVuY29kZXIpCj4gICAKPiAgIAlpZiAoZHNpLT5tb2RlX2ZsYWdzICYgTUlQSV9E U0lfTU9ERV9WSURFTykgewo+ICAgCQlEU0lfUE9SVF9XUklURShESVNQMF9DVFJMLAo+IC0JCQkg ICAgICAgVkM0X1NFVF9GSUVMRChkaXZpZGVyLCBEU0lfRElTUDBfUElYX0NMS19ESVYpIHwKPiAt CQkJICAgICAgIFZDNF9TRVRfRklFTEQoZm9ybWF0LCBEU0lfRElTUDBfUEZPUk1BVCkgfAo+ICsJ CQkgICAgICAgVkM0X1NFVF9GSUVMRChkc2ktPmRpdmlkZXIsCj4gKwkJCQkJICAgICBEU0lfRElT UDBfUElYX0NMS19ESVYpIHwKPiArCQkJICAgICAgIFZDNF9TRVRfRklFTEQoZHNpLT5mb3JtYXQs IERTSV9ESVNQMF9QRk9STUFUKSB8Cj4gICAJCQkgICAgICAgVkM0X1NFVF9GSUVMRChEU0lfRElT UDBfTFBfU1RPUF9QRVJGUkFNRSwKPiAgIAkJCQkJICAgICBEU0lfRElTUDBfTFBfU1RPUF9DVFJM KSB8Cj4gICAJCQkgICAgICAgRFNJX0RJU1AwX1NUX0VORCB8Cj4gQEAgLTEyNTUsOSArMTI5Miwz MSBAQCBzdGF0aWMgaW50IHZjNF9kc2lfaG9zdF9hdHRhY2goc3RydWN0IG1pcGlfZHNpX2hvc3Qg Kmhvc3QsCj4gICAKPiAgIAlkc2ktPmxhbmVzID0gZGV2aWNlLT5sYW5lczsKPiAgIAlkc2ktPmNo YW5uZWwgPSBkZXZpY2UtPmNoYW5uZWw7Cj4gLQlkc2ktPmZvcm1hdCA9IGRldmljZS0+Zm9ybWF0 Owo+ICAgCWRzaS0+bW9kZV9mbGFncyA9IGRldmljZS0+bW9kZV9mbGFnczsKPiAgIAo+ICsJc3dp dGNoIChkZXZpY2UtPmZvcm1hdCkgewo+ICsJY2FzZSBNSVBJX0RTSV9GTVRfUkdCODg4Ogo+ICsJ CWRzaS0+Zm9ybWF0ID0gRFNJX1BGT1JNQVRfUkdCODg4Owo+ICsJCWRzaS0+ZGl2aWRlciA9IDI0 IC8gZHNpLT5sYW5lczsKPiArCQlicmVhazsKPiArCWNhc2UgTUlQSV9EU0lfRk1UX1JHQjY2NjoK PiArCQlkc2ktPmZvcm1hdCA9IERTSV9QRk9STUFUX1JHQjY2NjsKPiArCQlkc2ktPmRpdmlkZXIg PSAyNCAvIGRzaS0+bGFuZXM7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIE1JUElfRFNJX0ZNVF9SR0I2 NjZfUEFDS0VEOgo+ICsJCWRzaS0+Zm9ybWF0ID0gRFNJX1BGT1JNQVRfUkdCNjY2X1BBQ0tFRDsK PiArCQlkc2ktPmRpdmlkZXIgPSAxOCAvIGRzaS0+bGFuZXM7Cj4gKwkJYnJlYWs7Cj4gKwljYXNl IE1JUElfRFNJX0ZNVF9SR0I1NjU6Cj4gKwkJZHNpLT5mb3JtYXQgPSBEU0lfUEZPUk1BVF9SR0I1 NjU7Cj4gKwkJZHNpLT5kaXZpZGVyID0gMTYgLyBkc2ktPmxhbmVzOwo+ICsJCWJyZWFrOwo+ICsJ ZGVmYXVsdDoKPiArCQlkZXZfZXJyKCZkc2ktPnBkZXYtPmRldiwgIlVua25vd24gRFNJIGZvcm1h dDogJWQuXG4iLAo+ICsJCQlkc2ktPmZvcm1hdCk7Cj4gKwkJcmV0dXJuIDA7Cj4gKwl9Cj4gKwo+ ICAgCWlmICghKGRzaS0+bW9kZV9mbGFncyAmIE1JUElfRFNJX01PREVfVklERU8pKSB7Cj4gICAJ CWRldl9lcnIoJmRzaS0+cGRldi0+ZGV2LAo+ICAgCQkJIk9ubHkgVklERU8gbW9kZSBwYW5lbHMg c3VwcG9ydGVkIGN1cnJlbnRseS5cbiIpOwo+IEBAIC0xMzA0LDYgKzEzNjMsNyBAQCBzdGF0aWMg Y29uc3Qgc3RydWN0IG1pcGlfZHNpX2hvc3Rfb3BzIHZjNF9kc2lfaG9zdF9vcHMgPSB7Cj4gICBz dGF0aWMgY29uc3Qgc3RydWN0IGRybV9lbmNvZGVyX2hlbHBlcl9mdW5jcyB2YzRfZHNpX2VuY29k ZXJfaGVscGVyX2Z1bmNzID0gewo+ICAgCS5kaXNhYmxlID0gdmM0X2RzaV9lbmNvZGVyX2Rpc2Fi bGUsCj4gICAJLmVuYWJsZSA9IHZjNF9kc2lfZW5jb2Rlcl9lbmFibGUsCj4gKwkubW9kZV9maXh1 cCA9IHZjNF9kc2lfZW5jb2Rlcl9tb2RlX2ZpeHVwLAo+ICAgfTsKPiAgIAo+ICAgc3RhdGljIGNv bnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgdmM0X2RzaV9kdF9tYXRjaFtdID0gewoKX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcg bGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRl c2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCg==