From mboxrd@z Thu Jan 1 00:00:00 1970 From: laurent.pinchart@ideasonboard.com (Laurent Pinchart) Date: Wed, 05 Sep 2018 16:46:05 +0300 Subject: [PATCH 04/10] phy: dphy: Add configuration helpers In-Reply-To: References: Message-ID: <3617916.Vq2Smf1hnZ@avalon> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Maxime, Thank you for the patch. On Wednesday, 5 September 2018 12:16:35 EEST Maxime Ripard wrote: > The MIPI D-PHY spec defines default values and boundaries for most of the > parameters it defines. Introduce helpers to help drivers get meaningful > values based on their current parameters, and validate the boundaries of > these parameters if needed. > > Signed-off-by: Maxime Ripard > --- > drivers/phy/Kconfig | 8 ++- > drivers/phy/Makefile | 1 +- > drivers/phy/phy-core-mipi-dphy.c | 160 +++++++++++++++++++++++++++++++- > include/linux/phy/phy-mipi-dphy.h | 6 +- > 4 files changed, 175 insertions(+) > create mode 100644 drivers/phy/phy-core-mipi-dphy.c > > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig > index 5c8d452e35e2..06bd22bd1f4a 100644 > --- a/drivers/phy/Kconfig > +++ b/drivers/phy/Kconfig > @@ -15,6 +15,14 @@ config GENERIC_PHY > phy users can obtain reference to the PHY. All the users of this > framework should select this config. > > +config GENERIC_PHY_MIPI_DPHY > + bool "MIPI D-PHY support" > + help > + Generic MIPI D-PHY support. > + > + Provides a number of helpers a core functions for MIPI D-PHY > + drivers to us. Do we really need to make this user-selectable ? > config PHY_LPC18XX_USB_OTG > tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver" > depends on OF && (ARCH_LPC18XX || COMPILE_TEST) > diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile > index 84e3bd9c5665..71c29d2b9af7 100644 > --- a/drivers/phy/Makefile > +++ b/drivers/phy/Makefile > @@ -4,6 +4,7 @@ > # > > obj-$(CONFIG_GENERIC_PHY) += phy-core.o > +obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o > obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o > obj-$(CONFIG_PHY_XGENE) += phy-xgene.o > obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o > diff --git a/drivers/phy/phy-core-mipi-dphy.c > b/drivers/phy/phy-core-mipi-dphy.c new file mode 100644 > index 000000000000..6c1ddc7734a2 > --- /dev/null > +++ b/drivers/phy/phy-core-mipi-dphy.c > @@ -0,0 +1,160 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2013 NVIDIA Corporation > + * Copyright (C) 2018 Cadence Design Systems Inc. > + */ > + > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +/* > + * Default D-PHY timings based on MIPI D-PHY specification. Derived from > the > + * valid ranges specified in Section 6.9, Table 14, Page 40 of the D-PHY > + * specification (v1.2) with minor adjustments. Could you list those adjustments ? > + */ > +int phy_mipi_dphy_get_default_config(unsigned long pixel_clock, > + unsigned int bpp, > + unsigned int lanes, > + struct phy_configure_opts_mipi_dphy *cfg) > +{ > + unsigned long hs_clk_rate; > + unsigned long ui; > + > + if (!cfg) > + return -EINVAL; Should we really expect cfg to be NULL ? > + hs_clk_rate = pixel_clock * bpp / lanes; > + ui = DIV_ROUND_UP(NSEC_PER_SEC, hs_clk_rate); > + > + cfg->clk_miss = 0; > + cfg->clk_post = 70 + 52 * ui; > + cfg->clk_pre = 8; > + cfg->clk_prepare = 65; > + cfg->clk_settle = 95; > + cfg->clk_term_en = 0; > + cfg->clk_trail = 80; > + cfg->clk_zero = 260; > + cfg->d_term_en = 0; > + cfg->eot = 0; > + cfg->hs_exit = 120; > + cfg->hs_prepare = 65 + 5 * ui; > + cfg->hs_zero = 145 + 5 * ui; > + cfg->hs_settle = 85 + 6 * ui; > + cfg->hs_skip = 40; > + > + /* > + * The MIPI D-PHY specification (Section 6.9, v1.2, Table 14, Page 40) > + * contains this formula as: > + * > + * T_HS-TRAIL = max(n * 8 * ui, 60 + n * 4 * ui) > + * > + * where n = 1 for forward-direction HS mode and n = 4 for reverse- > + * direction HS mode. There's only one setting and this function does > + * not parameterize on anything other that ui, so this code will > + * assumes that reverse-direction HS mode is supported and uses n = 4. > + */ > + cfg->hs_trail = max(4 * 8 * ui, 60 + 4 * 4 * ui); > + > + cfg->init = 100000; > + cfg->lpx = 60; > + cfg->ta_get = 5 * cfg->lpx; > + cfg->ta_go = 4 * cfg->lpx; > + cfg->ta_sure = 2 * cfg->lpx; > + cfg->wakeup = 1000000; > + > + cfg->hs_clk_rate = hs_clk_rate; > + cfg->lanes = lanes; > + > + return 0; > +} > +EXPORT_SYMBOL(phy_mipi_dphy_get_default_config); > + > +/* > + * Validate D-PHY configuration according to MIPI D-PHY specification > + * (v1.2, Section Section 6.9 "Global Operation Timing Parameters"). > + */ > +int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg) > +{ > + unsigned long ui; > + > + if (!cfg) > + return -EINVAL; Same here. > + ui = DIV_ROUND_UP(NSEC_PER_SEC, cfg->hs_clk_rate); > + > + if (cfg->clk_miss > 60) > + return -EINVAL; > + > + if (cfg->clk_post < (60 + 52 * ui)) > + return -EINVAL; > + > + if (cfg->clk_pre < 8) > + return -EINVAL; > + > + if (cfg->clk_prepare < 38 || cfg->clk_prepare > 95) > + return -EINVAL; > + > + if (cfg->clk_settle < 95 || cfg->clk_settle > 300) > + return -EINVAL; > + > + if (cfg->clk_term_en > 38) > + return -EINVAL; > + > + if (cfg->clk_trail < 60) > + return -EINVAL; > + > + if (cfg->clk_prepare + cfg->clk_zero < 300) > + return -EINVAL; > + > + if (cfg->d_term_en > 35 + 4 * ui) > + return -EINVAL; > + > + if (cfg->eot > 105 + 12 * ui) > + return -EINVAL; > + > + if (cfg->hs_exit < 100) > + return -EINVAL; > + > + if (cfg->hs_prepare < 40 + 4 * ui || > + cfg->hs_prepare > 85 + 6 * ui) > + return -EINVAL; > + > + if (cfg->hs_prepare + cfg->hs_zero < 145 + 10 * ui) > + return -EINVAL; > + > + if ((cfg->hs_settle < 85 + 6 * ui) || > + (cfg->hs_settle > 145 + 10 * ui)) > + return -EINVAL; > + > + if (cfg->hs_skip < 40 || cfg->hs_skip > 55 + 4 * ui) > + return -EINVAL; > + > + if (cfg->hs_trail < max(8 * ui, 60 + 4 * ui)) > + return -EINVAL; > + > + if (cfg->init < 100000) > + return -EINVAL; > + > + if (cfg->lpx < 50) > + return -EINVAL; > + > + if (cfg->ta_get != 5 * cfg->lpx) > + return -EINVAL; > + > + if (cfg->ta_go != 4 * cfg->lpx) > + return -EINVAL; > + > + if (cfg->ta_sure < cfg->lpx || cfg->ta_sure > 2 * cfg->lpx) > + return -EINVAL; > + > + if (cfg->wakeup < 1000000) > + return -EINVAL; > + > + return 0; > +} > +EXPORT_SYMBOL(phy_mipi_dphy_config_validate); > diff --git a/include/linux/phy/phy-mipi-dphy.h > b/include/linux/phy/phy-mipi-dphy.h index 792724145290..7656d057198f 100644 > --- a/include/linux/phy/phy-mipi-dphy.h > +++ b/include/linux/phy/phy-mipi-dphy.h > @@ -238,4 +238,10 @@ struct phy_configure_opts_mipi_dphy { > /* TODO: Add other modes (burst, commands, etc) */ > #define MIPI_DPHY_MODE_VIDEO_SYNC_PULSE BIT(0) > > +int phy_mipi_dphy_get_default_config(unsigned long pixel_clock, > + unsigned int bpp, > + unsigned int lanes, > + struct phy_configure_opts_mipi_dphy *cfg); > +int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy > *cfg); > + > #endif /* __PHY_MIPI_DPHY_H_ */ -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [PATCH 04/10] phy: dphy: Add configuration helpers Date: Wed, 05 Sep 2018 16:46:05 +0300 Message-ID: <3617916.Vq2Smf1hnZ@avalon> References: Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by gabe.freedesktop.org (Postfix) with ESMTPS id 099F46E486 for ; Wed, 5 Sep 2018 13:46:01 +0000 (UTC) In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Maxime Ripard Cc: Krzysztof Witos , Rafal Ciepiela , Boris Brezillon , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Kishon Vijay Abraham I , Chen-Yu Tsai , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org List-Id: dri-devel@lists.freedesktop.org SGkgTWF4aW1lLAoKVGhhbmsgeW91IGZvciB0aGUgcGF0Y2guCgpPbiBXZWRuZXNkYXksIDUgU2Vw dGVtYmVyIDIwMTggMTI6MTY6MzUgRUVTVCBNYXhpbWUgUmlwYXJkIHdyb3RlOgo+IFRoZSBNSVBJ IEQtUEhZIHNwZWMgZGVmaW5lcyBkZWZhdWx0IHZhbHVlcyBhbmQgYm91bmRhcmllcyBmb3IgbW9z dCBvZiB0aGUKPiBwYXJhbWV0ZXJzIGl0IGRlZmluZXMuIEludHJvZHVjZSBoZWxwZXJzIHRvIGhl bHAgZHJpdmVycyBnZXQgbWVhbmluZ2Z1bAo+IHZhbHVlcyBiYXNlZCBvbiB0aGVpciBjdXJyZW50 IHBhcmFtZXRlcnMsIGFuZCB2YWxpZGF0ZSB0aGUgYm91bmRhcmllcyBvZgo+IHRoZXNlIHBhcmFt ZXRlcnMgaWYgbmVlZGVkLgo+IAo+IFNpZ25lZC1vZmYtYnk6IE1heGltZSBSaXBhcmQgPG1heGlt ZS5yaXBhcmRAYm9vdGxpbi5jb20+Cj4gLS0tCj4gIGRyaXZlcnMvcGh5L0tjb25maWcgICAgICAg ICAgICAgICB8ICAgOCArKy0KPiAgZHJpdmVycy9waHkvTWFrZWZpbGUgICAgICAgICAgICAgIHwg ICAxICstCj4gIGRyaXZlcnMvcGh5L3BoeS1jb3JlLW1pcGktZHBoeS5jICB8IDE2MCArKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrLQo+ICBpbmNsdWRlL2xpbnV4L3BoeS9waHktbWlwaS1k cGh5LmggfCAgIDYgKy0KPiAgNCBmaWxlcyBjaGFuZ2VkLCAxNzUgaW5zZXJ0aW9ucygrKQo+ICBj cmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9waHkvcGh5LWNvcmUtbWlwaS1kcGh5LmMKPiAKPiBk aWZmIC0tZ2l0IGEvZHJpdmVycy9waHkvS2NvbmZpZyBiL2RyaXZlcnMvcGh5L0tjb25maWcKPiBp bmRleCA1YzhkNDUyZTM1ZTIuLjA2YmQyMmJkMWY0YSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL3Bo eS9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9waHkvS2NvbmZpZwo+IEBAIC0xNSw2ICsxNSwxNCBA QCBjb25maWcgR0VORVJJQ19QSFkKPiAgCSAgcGh5IHVzZXJzIGNhbiBvYnRhaW4gcmVmZXJlbmNl IHRvIHRoZSBQSFkuIEFsbCB0aGUgdXNlcnMgb2YgdGhpcwo+ICAJICBmcmFtZXdvcmsgc2hvdWxk IHNlbGVjdCB0aGlzIGNvbmZpZy4KPiAKPiArY29uZmlnIEdFTkVSSUNfUEhZX01JUElfRFBIWQo+ ICsJYm9vbCAiTUlQSSBELVBIWSBzdXBwb3J0Igo+ICsJaGVscAo+ICsJICBHZW5lcmljIE1JUEkg RC1QSFkgc3VwcG9ydC4KPiArCj4gKwkgIFByb3ZpZGVzIGEgbnVtYmVyIG9mIGhlbHBlcnMgYSBj b3JlIGZ1bmN0aW9ucyBmb3IgTUlQSSBELVBIWQo+ICsJICBkcml2ZXJzIHRvIHVzLgoKRG8gd2Ug cmVhbGx5IG5lZWQgdG8gbWFrZSB0aGlzIHVzZXItc2VsZWN0YWJsZSA/Cgo+ICBjb25maWcgUEhZ X0xQQzE4WFhfVVNCX09URwo+ICAJdHJpc3RhdGUgIk5YUCBMUEMxOHh4LzQzeHggU29DIFVTQiBP VEcgUEhZIGRyaXZlciIKPiAgCWRlcGVuZHMgb24gT0YgJiYgKEFSQ0hfTFBDMThYWCB8fCBDT01Q SUxFX1RFU1QpCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGh5L01ha2VmaWxlIGIvZHJpdmVycy9w aHkvTWFrZWZpbGUKPiBpbmRleCA4NGUzYmQ5YzU2NjUuLjcxYzI5ZDJiOWFmNyAxMDA2NDQKPiAt LS0gYS9kcml2ZXJzL3BoeS9NYWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvcGh5L01ha2VmaWxlCj4g QEAgLTQsNiArNCw3IEBACj4gICMKPiAKPiAgb2JqLSQoQ09ORklHX0dFTkVSSUNfUEhZKQkJKz0g cGh5LWNvcmUubwo+ICtvYmotJChDT05GSUdfR0VORVJJQ19QSFlfTUlQSV9EUEhZKQkrPSBwaHkt Y29yZS1taXBpLWRwaHkubwo+ICBvYmotJChDT05GSUdfUEhZX0xQQzE4WFhfVVNCX09URykJKz0g cGh5LWxwYzE4eHgtdXNiLW90Zy5vCj4gIG9iai0kKENPTkZJR19QSFlfWEdFTkUpCQkJKz0gcGh5 LXhnZW5lLm8KPiAgb2JqLSQoQ09ORklHX1BIWV9QSVNUQUNISU9fVVNCKQkJKz0gcGh5LXBpc3Rh Y2hpby11c2Iubwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3BoeS9waHktY29yZS1taXBpLWRwaHku Ywo+IGIvZHJpdmVycy9waHkvcGh5LWNvcmUtbWlwaS1kcGh5LmMgbmV3IGZpbGUgbW9kZSAxMDA2 NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAuLjZjMWRkYzc3MzRhMgo+IC0tLSAvZGV2L251bGwKPiAr KysgYi9kcml2ZXJzL3BoeS9waHktY29yZS1taXBpLWRwaHkuYwo+IEBAIC0wLDAgKzEsMTYwIEBA Cj4gKy8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wICovCj4gKy8qCj4gKyAqIENv cHlyaWdodCAoQykgMjAxMyBOVklESUEgQ29ycG9yYXRpb24KPiArICogQ29weXJpZ2h0IChDKSAy MDE4IENhZGVuY2UgRGVzaWduIFN5c3RlbXMgSW5jLgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxs aW51eC9lcnJuby5oPgo+ICsjaW5jbHVkZSA8bGludXgvZXhwb3J0Lmg+Cj4gKyNpbmNsdWRlIDxs aW51eC9rZXJuZWwuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3RpbWU2NC5oPgo+ICsKPiArI2luY2x1 ZGUgPGxpbnV4L3BoeS9waHkuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3BoeS9waHktbWlwaS1kcGh5 Lmg+Cj4gKwo+ICsvKgo+ICsgKiBEZWZhdWx0IEQtUEhZIHRpbWluZ3MgYmFzZWQgb24gTUlQSSBE LVBIWSBzcGVjaWZpY2F0aW9uLiBEZXJpdmVkIGZyb20KPiB0aGUKPiArICogdmFsaWQgcmFuZ2Vz IHNwZWNpZmllZCBpbiBTZWN0aW9uIDYuOSwgVGFibGUgMTQsIFBhZ2UgNDAgb2YgdGhlIEQtUEhZ Cj4gKyAqIHNwZWNpZmljYXRpb24gKHYxLjIpIHdpdGggbWlub3IgYWRqdXN0bWVudHMuCgpDb3Vs ZCB5b3UgbGlzdCB0aG9zZSBhZGp1c3RtZW50cyA/Cgo+ICsgKi8KPiAraW50IHBoeV9taXBpX2Rw aHlfZ2V0X2RlZmF1bHRfY29uZmlnKHVuc2lnbmVkIGxvbmcgcGl4ZWxfY2xvY2ssCj4gKwkJCQkg ICAgIHVuc2lnbmVkIGludCBicHAsCj4gKwkJCQkgICAgIHVuc2lnbmVkIGludCBsYW5lcywKPiAr CQkJCSAgICAgc3RydWN0IHBoeV9jb25maWd1cmVfb3B0c19taXBpX2RwaHkgKmNmZykKPiArewo+ ICsJdW5zaWduZWQgbG9uZyBoc19jbGtfcmF0ZTsKPiArCXVuc2lnbmVkIGxvbmcgdWk7Cj4gKwo+ ICsJaWYgKCFjZmcpCj4gKwkJcmV0dXJuIC1FSU5WQUw7CgpTaG91bGQgd2UgcmVhbGx5IGV4cGVj dCBjZmcgdG8gYmUgTlVMTCA/Cgo+ICsJaHNfY2xrX3JhdGUgPSBwaXhlbF9jbG9jayAqIGJwcCAv IGxhbmVzOwo+ICsJdWkgPSBESVZfUk9VTkRfVVAoTlNFQ19QRVJfU0VDLCBoc19jbGtfcmF0ZSk7 Cj4gKwo+ICsJY2ZnLT5jbGtfbWlzcyA9IDA7Cj4gKwljZmctPmNsa19wb3N0ID0gNzAgKyA1MiAq IHVpOwo+ICsJY2ZnLT5jbGtfcHJlID0gODsKPiArCWNmZy0+Y2xrX3ByZXBhcmUgPSA2NTsKPiAr CWNmZy0+Y2xrX3NldHRsZSA9IDk1Owo+ICsJY2ZnLT5jbGtfdGVybV9lbiA9IDA7Cj4gKwljZmct PmNsa190cmFpbCA9IDgwOwo+ICsJY2ZnLT5jbGtfemVybyA9IDI2MDsKPiArCWNmZy0+ZF90ZXJt X2VuID0gMDsKPiArCWNmZy0+ZW90ID0gMDsKPiArCWNmZy0+aHNfZXhpdCA9IDEyMDsKPiArCWNm Zy0+aHNfcHJlcGFyZSA9IDY1ICsgNSAqIHVpOwo+ICsJY2ZnLT5oc196ZXJvID0gMTQ1ICsgNSAq IHVpOwo+ICsJY2ZnLT5oc19zZXR0bGUgPSA4NSArIDYgKiB1aTsKPiArCWNmZy0+aHNfc2tpcCA9 IDQwOwo+ICsKPiArCS8qCj4gKwkgKiBUaGUgTUlQSSBELVBIWSBzcGVjaWZpY2F0aW9uIChTZWN0 aW9uIDYuOSwgdjEuMiwgVGFibGUgMTQsIFBhZ2UgNDApCj4gKwkgKiBjb250YWlucyB0aGlzIGZv cm11bGEgYXM6Cj4gKwkgKgo+ICsJICogICAgIFRfSFMtVFJBSUwgPSBtYXgobiAqIDggKiB1aSwg NjAgKyBuICogNCAqIHVpKQo+ICsJICoKPiArCSAqIHdoZXJlIG4gPSAxIGZvciBmb3J3YXJkLWRp cmVjdGlvbiBIUyBtb2RlIGFuZCBuID0gNCBmb3IgcmV2ZXJzZS0KPiArCSAqIGRpcmVjdGlvbiBI UyBtb2RlLiBUaGVyZSdzIG9ubHkgb25lIHNldHRpbmcgYW5kIHRoaXMgZnVuY3Rpb24gZG9lcwo+ ICsJICogbm90IHBhcmFtZXRlcml6ZSBvbiBhbnl0aGluZyBvdGhlciB0aGF0IHVpLCBzbyB0aGlz IGNvZGUgd2lsbAo+ICsJICogYXNzdW1lcyB0aGF0IHJldmVyc2UtZGlyZWN0aW9uIEhTIG1vZGUg aXMgc3VwcG9ydGVkIGFuZCB1c2VzIG4gPSA0Lgo+ICsJICovCj4gKwljZmctPmhzX3RyYWlsID0g bWF4KDQgKiA4ICogdWksIDYwICsgNCAqIDQgKiB1aSk7Cj4gKwo+ICsJY2ZnLT5pbml0ID0gMTAw MDAwOwo+ICsJY2ZnLT5scHggPSA2MDsKPiArCWNmZy0+dGFfZ2V0ID0gNSAqIGNmZy0+bHB4Owo+ ICsJY2ZnLT50YV9nbyA9IDQgKiBjZmctPmxweDsKPiArCWNmZy0+dGFfc3VyZSA9IDIgKiBjZmct PmxweDsKPiArCWNmZy0+d2FrZXVwID0gMTAwMDAwMDsKPiArCj4gKwljZmctPmhzX2Nsa19yYXRl ID0gaHNfY2xrX3JhdGU7Cj4gKwljZmctPmxhbmVzID0gbGFuZXM7Cj4gKwo+ICsJcmV0dXJuIDA7 Cj4gK30KPiArRVhQT1JUX1NZTUJPTChwaHlfbWlwaV9kcGh5X2dldF9kZWZhdWx0X2NvbmZpZyk7 Cj4gKwo+ICsvKgo+ICsgKiBWYWxpZGF0ZSBELVBIWSBjb25maWd1cmF0aW9uIGFjY29yZGluZyB0 byBNSVBJIEQtUEhZIHNwZWNpZmljYXRpb24KPiArICogKHYxLjIsIFNlY3Rpb24gU2VjdGlvbiA2 LjkgIkdsb2JhbCBPcGVyYXRpb24gVGltaW5nIFBhcmFtZXRlcnMiKS4KPiArICovCj4gK2ludCBw aHlfbWlwaV9kcGh5X2NvbmZpZ192YWxpZGF0ZShzdHJ1Y3QgcGh5X2NvbmZpZ3VyZV9vcHRzX21p cGlfZHBoeSAqY2ZnKQo+ICt7Cj4gKwl1bnNpZ25lZCBsb25nIHVpOwo+ICsKPiArCWlmICghY2Zn KQo+ICsJCXJldHVybiAtRUlOVkFMOwoKU2FtZSBoZXJlLgoKPiArCXVpID0gRElWX1JPVU5EX1VQ KE5TRUNfUEVSX1NFQywgY2ZnLT5oc19jbGtfcmF0ZSk7Cj4gKwo+ICsJaWYgKGNmZy0+Y2xrX21p c3MgPiA2MCkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlpZiAoY2ZnLT5jbGtfcG9zdCA8 ICg2MCArIDUyICogdWkpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWlmIChjZmctPmNs a19wcmUgPCA4KQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWlmIChjZmctPmNsa19wcmVw YXJlIDwgMzggfHwgY2ZnLT5jbGtfcHJlcGFyZSA+IDk1KQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ ICsKPiArCWlmIChjZmctPmNsa19zZXR0bGUgPCA5NSB8fCBjZmctPmNsa19zZXR0bGUgPiAzMDAp Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJaWYgKGNmZy0+Y2xrX3Rlcm1fZW4gPiAzOCkK PiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlpZiAoY2ZnLT5jbGtfdHJhaWwgPCA2MCkKPiAr CQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlpZiAoY2ZnLT5jbGtfcHJlcGFyZSArIGNmZy0+Y2xr X3plcm8gPCAzMDApCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJaWYgKGNmZy0+ZF90ZXJt X2VuID4gMzUgKyA0ICogdWkpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJaWYgKGNmZy0+ ZW90ID4gMTA1ICsgMTIgKiB1aSkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlpZiAoY2Zn LT5oc19leGl0IDwgMTAwKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWlmIChjZmctPmhz X3ByZXBhcmUgPCA0MCArIDQgKiB1aSB8fAo+ICsJICAgIGNmZy0+aHNfcHJlcGFyZSA+IDg1ICsg NiAqIHVpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWlmIChjZmctPmhzX3ByZXBhcmUg KyBjZmctPmhzX3plcm8gPCAxNDUgKyAxMCAqIHVpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsK PiArCWlmICgoY2ZnLT5oc19zZXR0bGUgPCA4NSArIDYgKiB1aSkgfHwKPiArCSAgICAoY2ZnLT5o c19zZXR0bGUgPiAxNDUgKyAxMCAqIHVpKSkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlp ZiAoY2ZnLT5oc19za2lwIDwgNDAgfHwgY2ZnLT5oc19za2lwID4gNTUgKyA0ICogdWkpCj4gKwkJ cmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJaWYgKGNmZy0+aHNfdHJhaWwgPCBtYXgoOCAqIHVpLCA2 MCArIDQgKiB1aSkpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJaWYgKGNmZy0+aW5pdCA8 IDEwMDAwMCkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlpZiAoY2ZnLT5scHggPCA1MCkK PiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlpZiAoY2ZnLT50YV9nZXQgIT0gNSAqIGNmZy0+ bHB4KQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWlmIChjZmctPnRhX2dvICE9IDQgKiBj ZmctPmxweCkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlpZiAoY2ZnLT50YV9zdXJlIDwg Y2ZnLT5scHggfHwgY2ZnLT50YV9zdXJlID4gMiAqIGNmZy0+bHB4KQo+ICsJCXJldHVybiAtRUlO VkFMOwo+ICsKPiArCWlmIChjZmctPndha2V1cCA8IDEwMDAwMDApCj4gKwkJcmV0dXJuIC1FSU5W QUw7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArRVhQT1JUX1NZTUJPTChwaHlfbWlwaV9kcGh5 X2NvbmZpZ192YWxpZGF0ZSk7Cj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvcGh5L3BoeS1t aXBpLWRwaHkuaAo+IGIvaW5jbHVkZS9saW51eC9waHkvcGh5LW1pcGktZHBoeS5oIGluZGV4IDc5 MjcyNDE0NTI5MC4uNzY1NmQwNTcxOThmIDEwMDY0NAo+IC0tLSBhL2luY2x1ZGUvbGludXgvcGh5 L3BoeS1taXBpLWRwaHkuaAo+ICsrKyBiL2luY2x1ZGUvbGludXgvcGh5L3BoeS1taXBpLWRwaHku aAo+IEBAIC0yMzgsNCArMjM4LDEwIEBAIHN0cnVjdCBwaHlfY29uZmlndXJlX29wdHNfbWlwaV9k cGh5IHsKPiAgLyogVE9ETzogQWRkIG90aGVyIG1vZGVzIChidXJzdCwgY29tbWFuZHMsIGV0Yykg Ki8KPiAgI2RlZmluZSBNSVBJX0RQSFlfTU9ERV9WSURFT19TWU5DX1BVTFNFCQlCSVQoMCkKPiAK PiAraW50IHBoeV9taXBpX2RwaHlfZ2V0X2RlZmF1bHRfY29uZmlnKHVuc2lnbmVkIGxvbmcgcGl4 ZWxfY2xvY2ssCj4gKwkJCQkgICAgIHVuc2lnbmVkIGludCBicHAsCj4gKwkJCQkgICAgIHVuc2ln bmVkIGludCBsYW5lcywKPiArCQkJCSAgICAgc3RydWN0IHBoeV9jb25maWd1cmVfb3B0c19taXBp X2RwaHkgKmNmZyk7Cj4gK2ludCBwaHlfbWlwaV9kcGh5X2NvbmZpZ192YWxpZGF0ZShzdHJ1Y3Qg cGh5X2NvbmZpZ3VyZV9vcHRzX21pcGlfZHBoeQo+ICpjZmcpOwo+ICsKPiAgI2VuZGlmIC8qIF9f UEhZX01JUElfRFBIWV9IXyAqLwoKCi0tIApSZWdhcmRzLAoKTGF1cmVudCBQaW5jaGFydAoKCgpf X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwg bWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0 cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from perceval.ideasonboard.com ([213.167.242.64]:57058 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726008AbeIESQU (ORCPT ); Wed, 5 Sep 2018 14:16:20 -0400 From: Laurent Pinchart To: Maxime Ripard Cc: Kishon Vijay Abraham I , Boris Brezillon , Thomas Petazzoni , linux-media@vger.kernel.org, Archit Taneja , Andrzej Hajda , Chen-Yu Tsai , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, Krzysztof Witos , Rafal Ciepiela Subject: Re: [PATCH 04/10] phy: dphy: Add configuration helpers Date: Wed, 05 Sep 2018 16:46:05 +0300 Message-ID: <3617916.Vq2Smf1hnZ@avalon> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-media-owner@vger.kernel.org List-ID: Hi Maxime, Thank you for the patch. On Wednesday, 5 September 2018 12:16:35 EEST Maxime Ripard wrote: > The MIPI D-PHY spec defines default values and boundaries for most of the > parameters it defines. Introduce helpers to help drivers get meaningful > values based on their current parameters, and validate the boundaries of > these parameters if needed. > > Signed-off-by: Maxime Ripard > --- > drivers/phy/Kconfig | 8 ++- > drivers/phy/Makefile | 1 +- > drivers/phy/phy-core-mipi-dphy.c | 160 +++++++++++++++++++++++++++++++- > include/linux/phy/phy-mipi-dphy.h | 6 +- > 4 files changed, 175 insertions(+) > create mode 100644 drivers/phy/phy-core-mipi-dphy.c > > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig > index 5c8d452e35e2..06bd22bd1f4a 100644 > --- a/drivers/phy/Kconfig > +++ b/drivers/phy/Kconfig > @@ -15,6 +15,14 @@ config GENERIC_PHY > phy users can obtain reference to the PHY. All the users of this > framework should select this config. > > +config GENERIC_PHY_MIPI_DPHY > + bool "MIPI D-PHY support" > + help > + Generic MIPI D-PHY support. > + > + Provides a number of helpers a core functions for MIPI D-PHY > + drivers to us. Do we really need to make this user-selectable ? > config PHY_LPC18XX_USB_OTG > tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver" > depends on OF && (ARCH_LPC18XX || COMPILE_TEST) > diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile > index 84e3bd9c5665..71c29d2b9af7 100644 > --- a/drivers/phy/Makefile > +++ b/drivers/phy/Makefile > @@ -4,6 +4,7 @@ > # > > obj-$(CONFIG_GENERIC_PHY) += phy-core.o > +obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o > obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o > obj-$(CONFIG_PHY_XGENE) += phy-xgene.o > obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o > diff --git a/drivers/phy/phy-core-mipi-dphy.c > b/drivers/phy/phy-core-mipi-dphy.c new file mode 100644 > index 000000000000..6c1ddc7734a2 > --- /dev/null > +++ b/drivers/phy/phy-core-mipi-dphy.c > @@ -0,0 +1,160 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2013 NVIDIA Corporation > + * Copyright (C) 2018 Cadence Design Systems Inc. > + */ > + > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +/* > + * Default D-PHY timings based on MIPI D-PHY specification. Derived from > the > + * valid ranges specified in Section 6.9, Table 14, Page 40 of the D-PHY > + * specification (v1.2) with minor adjustments. Could you list those adjustments ? > + */ > +int phy_mipi_dphy_get_default_config(unsigned long pixel_clock, > + unsigned int bpp, > + unsigned int lanes, > + struct phy_configure_opts_mipi_dphy *cfg) > +{ > + unsigned long hs_clk_rate; > + unsigned long ui; > + > + if (!cfg) > + return -EINVAL; Should we really expect cfg to be NULL ? > + hs_clk_rate = pixel_clock * bpp / lanes; > + ui = DIV_ROUND_UP(NSEC_PER_SEC, hs_clk_rate); > + > + cfg->clk_miss = 0; > + cfg->clk_post = 70 + 52 * ui; > + cfg->clk_pre = 8; > + cfg->clk_prepare = 65; > + cfg->clk_settle = 95; > + cfg->clk_term_en = 0; > + cfg->clk_trail = 80; > + cfg->clk_zero = 260; > + cfg->d_term_en = 0; > + cfg->eot = 0; > + cfg->hs_exit = 120; > + cfg->hs_prepare = 65 + 5 * ui; > + cfg->hs_zero = 145 + 5 * ui; > + cfg->hs_settle = 85 + 6 * ui; > + cfg->hs_skip = 40; > + > + /* > + * The MIPI D-PHY specification (Section 6.9, v1.2, Table 14, Page 40) > + * contains this formula as: > + * > + * T_HS-TRAIL = max(n * 8 * ui, 60 + n * 4 * ui) > + * > + * where n = 1 for forward-direction HS mode and n = 4 for reverse- > + * direction HS mode. There's only one setting and this function does > + * not parameterize on anything other that ui, so this code will > + * assumes that reverse-direction HS mode is supported and uses n = 4. > + */ > + cfg->hs_trail = max(4 * 8 * ui, 60 + 4 * 4 * ui); > + > + cfg->init = 100000; > + cfg->lpx = 60; > + cfg->ta_get = 5 * cfg->lpx; > + cfg->ta_go = 4 * cfg->lpx; > + cfg->ta_sure = 2 * cfg->lpx; > + cfg->wakeup = 1000000; > + > + cfg->hs_clk_rate = hs_clk_rate; > + cfg->lanes = lanes; > + > + return 0; > +} > +EXPORT_SYMBOL(phy_mipi_dphy_get_default_config); > + > +/* > + * Validate D-PHY configuration according to MIPI D-PHY specification > + * (v1.2, Section Section 6.9 "Global Operation Timing Parameters"). > + */ > +int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg) > +{ > + unsigned long ui; > + > + if (!cfg) > + return -EINVAL; Same here. > + ui = DIV_ROUND_UP(NSEC_PER_SEC, cfg->hs_clk_rate); > + > + if (cfg->clk_miss > 60) > + return -EINVAL; > + > + if (cfg->clk_post < (60 + 52 * ui)) > + return -EINVAL; > + > + if (cfg->clk_pre < 8) > + return -EINVAL; > + > + if (cfg->clk_prepare < 38 || cfg->clk_prepare > 95) > + return -EINVAL; > + > + if (cfg->clk_settle < 95 || cfg->clk_settle > 300) > + return -EINVAL; > + > + if (cfg->clk_term_en > 38) > + return -EINVAL; > + > + if (cfg->clk_trail < 60) > + return -EINVAL; > + > + if (cfg->clk_prepare + cfg->clk_zero < 300) > + return -EINVAL; > + > + if (cfg->d_term_en > 35 + 4 * ui) > + return -EINVAL; > + > + if (cfg->eot > 105 + 12 * ui) > + return -EINVAL; > + > + if (cfg->hs_exit < 100) > + return -EINVAL; > + > + if (cfg->hs_prepare < 40 + 4 * ui || > + cfg->hs_prepare > 85 + 6 * ui) > + return -EINVAL; > + > + if (cfg->hs_prepare + cfg->hs_zero < 145 + 10 * ui) > + return -EINVAL; > + > + if ((cfg->hs_settle < 85 + 6 * ui) || > + (cfg->hs_settle > 145 + 10 * ui)) > + return -EINVAL; > + > + if (cfg->hs_skip < 40 || cfg->hs_skip > 55 + 4 * ui) > + return -EINVAL; > + > + if (cfg->hs_trail < max(8 * ui, 60 + 4 * ui)) > + return -EINVAL; > + > + if (cfg->init < 100000) > + return -EINVAL; > + > + if (cfg->lpx < 50) > + return -EINVAL; > + > + if (cfg->ta_get != 5 * cfg->lpx) > + return -EINVAL; > + > + if (cfg->ta_go != 4 * cfg->lpx) > + return -EINVAL; > + > + if (cfg->ta_sure < cfg->lpx || cfg->ta_sure > 2 * cfg->lpx) > + return -EINVAL; > + > + if (cfg->wakeup < 1000000) > + return -EINVAL; > + > + return 0; > +} > +EXPORT_SYMBOL(phy_mipi_dphy_config_validate); > diff --git a/include/linux/phy/phy-mipi-dphy.h > b/include/linux/phy/phy-mipi-dphy.h index 792724145290..7656d057198f 100644 > --- a/include/linux/phy/phy-mipi-dphy.h > +++ b/include/linux/phy/phy-mipi-dphy.h > @@ -238,4 +238,10 @@ struct phy_configure_opts_mipi_dphy { > /* TODO: Add other modes (burst, commands, etc) */ > #define MIPI_DPHY_MODE_VIDEO_SYNC_PULSE BIT(0) > > +int phy_mipi_dphy_get_default_config(unsigned long pixel_clock, > + unsigned int bpp, > + unsigned int lanes, > + struct phy_configure_opts_mipi_dphy *cfg); > +int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy > *cfg); > + > #endif /* __PHY_MIPI_DPHY_H_ */ -- Regards, Laurent Pinchart