From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753027AbeDSJdd (ORCPT ); Thu, 19 Apr 2018 05:33:33 -0400 Received: from mirror2.csie.ntu.edu.tw ([140.112.30.76]:35708 "EHLO wens.csie.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752778AbeDSJcf (ORCPT ); Thu, 19 Apr 2018 05:32:35 -0400 From: Chen-Yu Tsai To: Maxime Ripard , David Airlie , Thierry Reding , Rob Herring , Mark Rutland Cc: Jonathan Liu , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Chen-Yu Tsai Subject: [PATCH 3/6] drm/sun4i: tcon: Add dithering support for RGB565/RGB666 LCD panels Date: Thu, 19 Apr 2018 17:32:22 +0800 Message-Id: <20180419093225.614-4-wens@csie.org> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180419093225.614-1-wens@csie.org> References: <20180419093225.614-1-wens@csie.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jonathan Liu The hardware supports dithering on TCON channel 0 which is used for LCD panels. Dithering is a method of approximating a color from a mixture of other colors when the required color isn't available. It reduces color banding artifacts that can be observed when displaying gradients (e.g. grayscale gradients). This may occur when the image that needs to be displayed is 24-bit but the LCD panel is a lower bit depth and does not perform dithering on its own. Signed-off-by: Jonathan Liu [wens@csie.org: check display_info.bpc first; handle LVDS and MIPI DSI] Signed-off-by: Chen-Yu Tsai --- Hi Maxime, The dithering parameters used here are different from the ones you used in your MIPI DSI series. You might want to check if it still works for you. --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 63 +++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 2bd53ef7d4b8..827518f4790e 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -276,8 +277,59 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon, SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); } +static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon *tcon, + const struct drm_connector *connector) +{ + u32 bus_format = 0; + u32 val = 0; + + /* XXX Would this ever happen? */ + if (!connector) + return; + + /* + * FIXME: Undocumented bits + * + * The whole dithering process and these parameters are not + * explained in the vendor documents or BSP kernel code. + */ + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PR_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PG_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PB_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LR_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LG_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LB_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL0_REG, 0x01010000); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL1_REG, 0x15151111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL2_REG, 0x57575555); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL3_REG, 0x7f7f7777); + + /* Do dithering if panel only supports 6 bits per color */ + if (connector->display_info.bpc == 6) + val |= SUN4I_TCON0_FRM_CTL_EN; + + if (connector->display_info.num_bus_formats == 1) + bus_format = connector->display_info.bus_formats[0]; + + /* Check the connection format */ + switch (bus_format) { + case MEDIA_BUS_FMT_RGB565_1X16: + /* R and B components are only 5 bits deep */ + val |= SUN4I_TCON0_FRM_CTL_MODE_R; + val |= SUN4I_TCON0_FRM_CTL_MODE_B; + case MEDIA_BUS_FMT_RGB666_1X18: + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: + /* Fall through: enable dithering */ + val |= SUN4I_TCON0_FRM_CTL_EN; + break; + } + + /* Write dithering settings */ + regmap_write(tcon->regs, SUN4I_TCON_FRM_CTL_REG, val); +} + static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon, - struct drm_encoder *encoder, + const struct drm_encoder *encoder, const struct drm_display_mode *mode) { /* TODO support normal CPU interface modes */ @@ -293,6 +345,9 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon, sun4i_tcon0_mode_set_common(tcon, mode); + /* Set dithering if needed */ + sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder)); + regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, SUN4I_TCON0_CTL_IF_MASK, SUN4I_TCON0_CTL_IF_8080); @@ -358,6 +413,9 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon, tcon->dclk_max_div = 7; sun4i_tcon0_mode_set_common(tcon, mode); + /* Set dithering if needed */ + sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder)); + /* Adjust clock delay */ clk_delay = sun4i_tcon_get_clk_delay(mode, 0); regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, @@ -434,6 +492,9 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, tcon->dclk_max_div = 127; sun4i_tcon0_mode_set_common(tcon, mode); + /* Set dithering if needed */ + sun4i_tcon0_mode_set_dithering(tcon, tcon->panel->connector); + /* Adjust clock delay */ clk_delay = sun4i_tcon_get_clk_delay(mode, 0); regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, -- 2.17.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Chen-Yu Tsai Subject: [PATCH 3/6] drm/sun4i: tcon: Add dithering support for RGB565/RGB666 LCD panels Date: Thu, 19 Apr 2018 17:32:22 +0800 Message-ID: <20180419093225.614-4-wens@csie.org> References: <20180419093225.614-1-wens@csie.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20180419093225.614-1-wens@csie.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Maxime Ripard , David Airlie , Thierry Reding , Rob Herring , Mark Rutland Cc: devicetree@vger.kernel.org, Jonathan Liu , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Chen-Yu Tsai , linux-arm-kernel@lists.infradead.org List-Id: devicetree@vger.kernel.org RnJvbTogSm9uYXRoYW4gTGl1IDxuZXQxNDdAZ21haWwuY29tPgoKVGhlIGhhcmR3YXJlIHN1cHBv cnRzIGRpdGhlcmluZyBvbiBUQ09OIGNoYW5uZWwgMCB3aGljaCBpcyB1c2VkIGZvciBMQ0QKcGFu ZWxzLgoKRGl0aGVyaW5nIGlzIGEgbWV0aG9kIG9mIGFwcHJveGltYXRpbmcgYSBjb2xvciBmcm9t IGEgbWl4dHVyZSBvZiBvdGhlcgpjb2xvcnMgd2hlbiB0aGUgcmVxdWlyZWQgY29sb3IgaXNuJ3Qg YXZhaWxhYmxlLiBJdCByZWR1Y2VzIGNvbG9yCmJhbmRpbmcgYXJ0aWZhY3RzIHRoYXQgY2FuIGJl IG9ic2VydmVkIHdoZW4gZGlzcGxheWluZyBncmFkaWVudHMKKGUuZy4gZ3JheXNjYWxlIGdyYWRp ZW50cykuIFRoaXMgbWF5IG9jY3VyIHdoZW4gdGhlIGltYWdlIHRoYXQgbmVlZHMKdG8gYmUgZGlz cGxheWVkIGlzIDI0LWJpdCBidXQgdGhlIExDRCBwYW5lbCBpcyBhIGxvd2VyIGJpdCBkZXB0aCBh bmQKZG9lcyBub3QgcGVyZm9ybSBkaXRoZXJpbmcgb24gaXRzIG93bi4KClNpZ25lZC1vZmYtYnk6 IEpvbmF0aGFuIExpdSA8bmV0MTQ3QGdtYWlsLmNvbT4KW3dlbnNAY3NpZS5vcmc6IGNoZWNrIGRp c3BsYXlfaW5mby5icGMgZmlyc3Q7IGhhbmRsZSBMVkRTIGFuZCBNSVBJIERTSV0KU2lnbmVkLW9m Zi1ieTogQ2hlbi1ZdSBUc2FpIDx3ZW5zQGNzaWUub3JnPgotLS0KCkhpIE1heGltZSwKClRoZSBk aXRoZXJpbmcgcGFyYW1ldGVycyB1c2VkIGhlcmUgYXJlIGRpZmZlcmVudCBmcm9tIHRoZSBvbmVz IHlvdSB1c2VkCmluIHlvdXIgTUlQSSBEU0kgc2VyaWVzLiBZb3UgbWlnaHQgd2FudCB0byBjaGVj ayBpZiBpdCBzdGlsbCB3b3JrcyBmb3IKeW91LgoKLS0tCiBkcml2ZXJzL2dwdS9kcm0vc3VuNGkv c3VuNGlfdGNvbi5jIHwgNjMgKysrKysrKysrKysrKysrKysrKysrKysrKysrKystCiAxIGZpbGUg Y2hhbmdlZCwgNjIgaW5zZXJ0aW9ucygrKSwgMSBkZWxldGlvbigtKQoKZGlmZiAtLWdpdCBhL2Ry aXZlcnMvZ3B1L2RybS9zdW40aS9zdW40aV90Y29uLmMgYi9kcml2ZXJzL2dwdS9kcm0vc3VuNGkv c3VuNGlfdGNvbi5jCmluZGV4IDJiZDUzZWY3ZDRiOC4uODI3NTE4ZjQ3OTBlIDEwMDY0NAotLS0g YS9kcml2ZXJzL2dwdS9kcm0vc3VuNGkvc3VuNGlfdGNvbi5jCisrKyBiL2RyaXZlcnMvZ3B1L2Ry bS9zdW40aS9zdW40aV90Y29uLmMKQEAgLTEyLDYgKzEyLDcgQEAKIAogI2luY2x1ZGUgPGRybS9k cm1QLmg+CiAjaW5jbHVkZSA8ZHJtL2RybV9hdG9taWNfaGVscGVyLmg+CisjaW5jbHVkZSA8ZHJt L2RybV9jb25uZWN0b3IuaD4KICNpbmNsdWRlIDxkcm0vZHJtX2NydGMuaD4KICNpbmNsdWRlIDxk cm0vZHJtX2NydGNfaGVscGVyLmg+CiAjaW5jbHVkZSA8ZHJtL2RybV9lbmNvZGVyLmg+CkBAIC0y NzYsOCArMjc3LDU5IEBAIHN0YXRpYyB2b2lkIHN1bjRpX3Rjb24wX21vZGVfc2V0X2NvbW1vbihz dHJ1Y3Qgc3VuNGlfdGNvbiAqdGNvbiwKIAkJICAgICBTVU40SV9UQ09OMF9CQVNJQzBfWShtb2Rl LT5jcnRjX3ZkaXNwbGF5KSk7CiB9CiAKK3N0YXRpYyB2b2lkIHN1bjRpX3Rjb24wX21vZGVfc2V0 X2RpdGhlcmluZyhzdHJ1Y3Qgc3VuNGlfdGNvbiAqdGNvbiwKKwkJCQkJICAgY29uc3Qgc3RydWN0 IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvcikKK3sKKwl1MzIgYnVzX2Zvcm1hdCA9IDA7CisJdTMy IHZhbCA9IDA7CisKKwkvKiBYWFggV291bGQgdGhpcyBldmVyIGhhcHBlbj8gKi8KKwlpZiAoIWNv bm5lY3RvcikKKwkJcmV0dXJuOworCisJLyoKKwkgKiBGSVhNRTogVW5kb2N1bWVudGVkIGJpdHMK KwkgKgorCSAqIFRoZSB3aG9sZSBkaXRoZXJpbmcgcHJvY2VzcyBhbmQgdGhlc2UgcGFyYW1ldGVy cyBhcmUgbm90CisJICogZXhwbGFpbmVkIGluIHRoZSB2ZW5kb3IgZG9jdW1lbnRzIG9yIEJTUCBr ZXJuZWwgY29kZS4KKwkgKi8KKwlyZWdtYXBfd3JpdGUodGNvbi0+cmVncywgU1VONElfVENPTjBf RlJNX1NFRURfUFJfUkVHLCAweDExMTExMTExKTsKKwlyZWdtYXBfd3JpdGUodGNvbi0+cmVncywg U1VONElfVENPTjBfRlJNX1NFRURfUEdfUkVHLCAweDExMTExMTExKTsKKwlyZWdtYXBfd3JpdGUo dGNvbi0+cmVncywgU1VONElfVENPTjBfRlJNX1NFRURfUEJfUkVHLCAweDExMTExMTExKTsKKwly ZWdtYXBfd3JpdGUodGNvbi0+cmVncywgU1VONElfVENPTjBfRlJNX1NFRURfTFJfUkVHLCAweDEx MTExMTExKTsKKwlyZWdtYXBfd3JpdGUodGNvbi0+cmVncywgU1VONElfVENPTjBfRlJNX1NFRURf TEdfUkVHLCAweDExMTExMTExKTsKKwlyZWdtYXBfd3JpdGUodGNvbi0+cmVncywgU1VONElfVENP TjBfRlJNX1NFRURfTEJfUkVHLCAweDExMTExMTExKTsKKwlyZWdtYXBfd3JpdGUodGNvbi0+cmVn cywgU1VONElfVENPTjBfRlJNX1RCTDBfUkVHLCAweDAxMDEwMDAwKTsKKwlyZWdtYXBfd3JpdGUo dGNvbi0+cmVncywgU1VONElfVENPTjBfRlJNX1RCTDFfUkVHLCAweDE1MTUxMTExKTsKKwlyZWdt YXBfd3JpdGUodGNvbi0+cmVncywgU1VONElfVENPTjBfRlJNX1RCTDJfUkVHLCAweDU3NTc1NTU1 KTsKKwlyZWdtYXBfd3JpdGUodGNvbi0+cmVncywgU1VONElfVENPTjBfRlJNX1RCTDNfUkVHLCAw eDdmN2Y3Nzc3KTsKKworCS8qIERvIGRpdGhlcmluZyBpZiBwYW5lbCBvbmx5IHN1cHBvcnRzIDYg Yml0cyBwZXIgY29sb3IgKi8KKwlpZiAoY29ubmVjdG9yLT5kaXNwbGF5X2luZm8uYnBjID09IDYp CisJCXZhbCB8PSBTVU40SV9UQ09OMF9GUk1fQ1RMX0VOOworCisJaWYgKGNvbm5lY3Rvci0+ZGlz cGxheV9pbmZvLm51bV9idXNfZm9ybWF0cyA9PSAxKQorCQlidXNfZm9ybWF0ID0gY29ubmVjdG9y LT5kaXNwbGF5X2luZm8uYnVzX2Zvcm1hdHNbMF07CisKKwkvKiBDaGVjayB0aGUgY29ubmVjdGlv biBmb3JtYXQgKi8KKwlzd2l0Y2ggKGJ1c19mb3JtYXQpIHsKKwljYXNlIE1FRElBX0JVU19GTVRf UkdCNTY1XzFYMTY6CisJCS8qIFIgYW5kIEIgY29tcG9uZW50cyBhcmUgb25seSA1IGJpdHMgZGVl cCAqLworCQl2YWwgfD0gU1VONElfVENPTjBfRlJNX0NUTF9NT0RFX1I7CisJCXZhbCB8PSBTVU40 SV9UQ09OMF9GUk1fQ1RMX01PREVfQjsKKwljYXNlIE1FRElBX0JVU19GTVRfUkdCNjY2XzFYMTg6 CisJY2FzZSBNRURJQV9CVVNfRk1UX1JHQjY2Nl8xWDdYM19TUFdHOgorCQkvKiBGYWxsIHRocm91 Z2g6IGVuYWJsZSBkaXRoZXJpbmcgKi8KKwkJdmFsIHw9IFNVTjRJX1RDT04wX0ZSTV9DVExfRU47 CisJCWJyZWFrOworCX0KKworCS8qIFdyaXRlIGRpdGhlcmluZyBzZXR0aW5ncyAqLworCXJlZ21h cF93cml0ZSh0Y29uLT5yZWdzLCBTVU40SV9UQ09OX0ZSTV9DVExfUkVHLCB2YWwpOworfQorCiBz dGF0aWMgdm9pZCBzdW40aV90Y29uMF9tb2RlX3NldF9jcHUoc3RydWN0IHN1bjRpX3Rjb24gKnRj b24sCi0JCQkJICAgICBzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIsCisJCQkJICAgICBjb25z dCBzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIsCiAJCQkJICAgICBjb25zdCBzdHJ1Y3QgZHJt X2Rpc3BsYXlfbW9kZSAqbW9kZSkKIHsKIAkvKiBUT0RPIHN1cHBvcnQgbm9ybWFsIENQVSBpbnRl cmZhY2UgbW9kZXMgKi8KQEAgLTI5Myw2ICszNDUsOSBAQCBzdGF0aWMgdm9pZCBzdW40aV90Y29u MF9tb2RlX3NldF9jcHUoc3RydWN0IHN1bjRpX3Rjb24gKnRjb24sCiAKIAlzdW40aV90Y29uMF9t b2RlX3NldF9jb21tb24odGNvbiwgbW9kZSk7CiAKKwkvKiBTZXQgZGl0aGVyaW5nIGlmIG5lZWRl ZCAqLworCXN1bjRpX3Rjb24wX21vZGVfc2V0X2RpdGhlcmluZyh0Y29uLCBzdW40aV90Y29uX2dl dF9jb25uZWN0b3IoZW5jb2RlcikpOworCiAJcmVnbWFwX3VwZGF0ZV9iaXRzKHRjb24tPnJlZ3Ms IFNVTjRJX1RDT04wX0NUTF9SRUcsCiAJCQkgICBTVU40SV9UQ09OMF9DVExfSUZfTUFTSywKIAkJ CSAgIFNVTjRJX1RDT04wX0NUTF9JRl84MDgwKTsKQEAgLTM1OCw2ICs0MTMsOSBAQCBzdGF0aWMg dm9pZCBzdW40aV90Y29uMF9tb2RlX3NldF9sdmRzKHN0cnVjdCBzdW40aV90Y29uICp0Y29uLAog CXRjb24tPmRjbGtfbWF4X2RpdiA9IDc7CiAJc3VuNGlfdGNvbjBfbW9kZV9zZXRfY29tbW9uKHRj b24sIG1vZGUpOwogCisJLyogU2V0IGRpdGhlcmluZyBpZiBuZWVkZWQgKi8KKwlzdW40aV90Y29u MF9tb2RlX3NldF9kaXRoZXJpbmcodGNvbiwgc3VuNGlfdGNvbl9nZXRfY29ubmVjdG9yKGVuY29k ZXIpKTsKKwogCS8qIEFkanVzdCBjbG9jayBkZWxheSAqLwogCWNsa19kZWxheSA9IHN1bjRpX3Rj b25fZ2V0X2Nsa19kZWxheShtb2RlLCAwKTsKIAlyZWdtYXBfdXBkYXRlX2JpdHModGNvbi0+cmVn cywgU1VONElfVENPTjBfQ1RMX1JFRywKQEAgLTQzNCw2ICs0OTIsOSBAQCBzdGF0aWMgdm9pZCBz dW40aV90Y29uMF9tb2RlX3NldF9yZ2Ioc3RydWN0IHN1bjRpX3Rjb24gKnRjb24sCiAJdGNvbi0+ ZGNsa19tYXhfZGl2ID0gMTI3OwogCXN1bjRpX3Rjb24wX21vZGVfc2V0X2NvbW1vbih0Y29uLCBt b2RlKTsKIAorCS8qIFNldCBkaXRoZXJpbmcgaWYgbmVlZGVkICovCisJc3VuNGlfdGNvbjBfbW9k ZV9zZXRfZGl0aGVyaW5nKHRjb24sIHRjb24tPnBhbmVsLT5jb25uZWN0b3IpOworCiAJLyogQWRq dXN0IGNsb2NrIGRlbGF5ICovCiAJY2xrX2RlbGF5ID0gc3VuNGlfdGNvbl9nZXRfY2xrX2RlbGF5 KG1vZGUsIDApOwogCXJlZ21hcF91cGRhdGVfYml0cyh0Y29uLT5yZWdzLCBTVU40SV9UQ09OMF9D VExfUkVHLAotLSAKMi4xNy4wCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVz a3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9k cmktZGV2ZWwK From mboxrd@z Thu Jan 1 00:00:00 1970 From: wens@csie.org (Chen-Yu Tsai) Date: Thu, 19 Apr 2018 17:32:22 +0800 Subject: [PATCH 3/6] drm/sun4i: tcon: Add dithering support for RGB565/RGB666 LCD panels In-Reply-To: <20180419093225.614-1-wens@csie.org> References: <20180419093225.614-1-wens@csie.org> Message-ID: <20180419093225.614-4-wens@csie.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org From: Jonathan Liu The hardware supports dithering on TCON channel 0 which is used for LCD panels. Dithering is a method of approximating a color from a mixture of other colors when the required color isn't available. It reduces color banding artifacts that can be observed when displaying gradients (e.g. grayscale gradients). This may occur when the image that needs to be displayed is 24-bit but the LCD panel is a lower bit depth and does not perform dithering on its own. Signed-off-by: Jonathan Liu [wens at csie.org: check display_info.bpc first; handle LVDS and MIPI DSI] Signed-off-by: Chen-Yu Tsai --- Hi Maxime, The dithering parameters used here are different from the ones you used in your MIPI DSI series. You might want to check if it still works for you. --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 63 +++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index 2bd53ef7d4b8..827518f4790e 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -276,8 +277,59 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon, SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); } +static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon *tcon, + const struct drm_connector *connector) +{ + u32 bus_format = 0; + u32 val = 0; + + /* XXX Would this ever happen? */ + if (!connector) + return; + + /* + * FIXME: Undocumented bits + * + * The whole dithering process and these parameters are not + * explained in the vendor documents or BSP kernel code. + */ + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PR_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PG_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PB_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LR_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LG_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LB_REG, 0x11111111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL0_REG, 0x01010000); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL1_REG, 0x15151111); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL2_REG, 0x57575555); + regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL3_REG, 0x7f7f7777); + + /* Do dithering if panel only supports 6 bits per color */ + if (connector->display_info.bpc == 6) + val |= SUN4I_TCON0_FRM_CTL_EN; + + if (connector->display_info.num_bus_formats == 1) + bus_format = connector->display_info.bus_formats[0]; + + /* Check the connection format */ + switch (bus_format) { + case MEDIA_BUS_FMT_RGB565_1X16: + /* R and B components are only 5 bits deep */ + val |= SUN4I_TCON0_FRM_CTL_MODE_R; + val |= SUN4I_TCON0_FRM_CTL_MODE_B; + case MEDIA_BUS_FMT_RGB666_1X18: + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: + /* Fall through: enable dithering */ + val |= SUN4I_TCON0_FRM_CTL_EN; + break; + } + + /* Write dithering settings */ + regmap_write(tcon->regs, SUN4I_TCON_FRM_CTL_REG, val); +} + static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon, - struct drm_encoder *encoder, + const struct drm_encoder *encoder, const struct drm_display_mode *mode) { /* TODO support normal CPU interface modes */ @@ -293,6 +345,9 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon, sun4i_tcon0_mode_set_common(tcon, mode); + /* Set dithering if needed */ + sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder)); + regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, SUN4I_TCON0_CTL_IF_MASK, SUN4I_TCON0_CTL_IF_8080); @@ -358,6 +413,9 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon, tcon->dclk_max_div = 7; sun4i_tcon0_mode_set_common(tcon, mode); + /* Set dithering if needed */ + sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder)); + /* Adjust clock delay */ clk_delay = sun4i_tcon_get_clk_delay(mode, 0); regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, @@ -434,6 +492,9 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, tcon->dclk_max_div = 127; sun4i_tcon0_mode_set_common(tcon, mode); + /* Set dithering if needed */ + sun4i_tcon0_mode_set_dithering(tcon, tcon->panel->connector); + /* Adjust clock delay */ clk_delay = sun4i_tcon_get_clk_delay(mode, 0); regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, -- 2.17.0