lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sat, 20 Jul 2019 05:07:05 +0800
From:   kbuild test robot <lkp@...el.com>
To:     Zeng Tao <prime.zeng@...ilicon.com>
Cc:     kbuild-all@...org, prime.zeng@...ilicon.com, kishon@...com,
        Maxime Ripard <maxime.ripard@...tlin.com>,
        Chen-Yu Tsai <wens@...e.org>,
        Paul Kocialkowski <paul.kocialkowski@...tlin.com>,
        Sakari Ailus <sakari.ailus@...ux.intel.com>,
        linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org
Subject: Re: [PATCH] phy: Change the configuration interface param to void*
 to make it more general

Hi Zeng,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[cannot apply to v5.2 next-20190719]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Zeng-Tao/phy-Change-the-configuration-interface-param-to-void-to-make-it-more-general/20190713-213420
config: arm64-allmodconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 7.4.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.4.0 make.cross ARCH=arm64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@...el.com>

All errors (new ones prefixed by >>):

   drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c: In function 'sun6i_dsi_encoder_enable':
>> drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:720:8: error: variable 'opts' has initializer but incomplete type
     union phy_configure_opts opts = { 0 };
           ^~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:720:36: warning: excess elements in union initializer
     union phy_configure_opts opts = { 0 };
                                       ^
   drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:720:36: note: (near initialization for 'opts')
>> drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:720:27: error: storage size of 'opts' isn't known
     union phy_configure_opts opts = { 0 };
                              ^~~~
   drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c:720:27: warning: unused variable 'opts' [-Wunused-variable]
--
>> drivers/gpu/drm/bridge/cdns-dsi.c:431:27: error: field 'phy_opts' has incomplete type
     union phy_configure_opts phy_opts;
                              ^~~~~~~~
--
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:155:16: warning: 'struct phy_configure_opts_mipi_dphy' declared inside parameter list will not be visible outside of this definition or declaration
            struct phy_configure_opts_mipi_dphy *dphy_opts,
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c: In function 'mixel_dphy_config_from_opts':
>> drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:165:15: error: dereferencing pointer to incomplete type 'struct phy_configure_opts_mipi_dphy'
     if (dphy_opts->hs_clk_rate > DATA_RATE_MAX_SPEED ||
                  ^~
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c: At top level:
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:320:56: warning: 'union phy_configure_opts' declared inside parameter list will not be visible outside of this definition or declaration
    static int mixel_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
                                                           ^~~~~~~~~~~~~~~~~~
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c: In function 'mixel_dphy_configure':
>> drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:326:46: error: dereferencing pointer to incomplete type 'union phy_configure_opts'
     ret = mixel_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
                                                 ^~
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c: At top level:
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:349:17: warning: 'union phy_configure_opts' declared inside parameter list will not be visible outside of this definition or declaration
              union phy_configure_opts *opts)
                    ^~~~~~~~~~~~~~~~~~
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c: In function 'mixel_dphy_validate':
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:356:47: error: dereferencing pointer to incomplete type 'union phy_configure_opts'
     return mixel_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
                                                  ^~
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c: At top level:
>> drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:419:15: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .configure = mixel_dphy_configure,
                  ^~~~~~~~~~~~~~~~~~~~
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:419:15: note: (near initialization for 'mixel_dphy_phy_ops.configure')
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:420:14: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .validate = mixel_dphy_validate,
                 ^~~~~~~~~~~~~~~~~~~
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:420:14: note: (near initialization for 'mixel_dphy_phy_ops.validate')
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c: In function 'mixel_dphy_validate':
   drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c:357:1: warning: control reaches end of non-void function [-Wreturn-type]
    }
    ^
   cc1: some warnings being treated as errors

vim +165 drivers/phy/freescale/phy-fsl-imx8-mipi-dphy.c

f4c8116e294b12c Guido Günther 2019-06-20  153  
f4c8116e294b12c Guido Günther 2019-06-20  154  static int mixel_dphy_config_from_opts(struct phy *phy,
f4c8116e294b12c Guido Günther 2019-06-20 @155  	       struct phy_configure_opts_mipi_dphy *dphy_opts,
f4c8116e294b12c Guido Günther 2019-06-20  156  	       struct mixel_dphy_cfg *cfg)
f4c8116e294b12c Guido Günther 2019-06-20  157  {
f4c8116e294b12c Guido Günther 2019-06-20  158  	struct mixel_dphy_priv *priv = dev_get_drvdata(phy->dev.parent);
f4c8116e294b12c Guido Günther 2019-06-20  159  	unsigned long ref_clk = clk_get_rate(priv->phy_ref_clk);
f4c8116e294b12c Guido Günther 2019-06-20  160  	u32 lp_t, numerator, denominator;
f4c8116e294b12c Guido Günther 2019-06-20  161  	unsigned long long tmp;
f4c8116e294b12c Guido Günther 2019-06-20  162  	u32 n;
f4c8116e294b12c Guido Günther 2019-06-20  163  	int i;
f4c8116e294b12c Guido Günther 2019-06-20  164  
f4c8116e294b12c Guido Günther 2019-06-20 @165  	if (dphy_opts->hs_clk_rate > DATA_RATE_MAX_SPEED ||
f4c8116e294b12c Guido Günther 2019-06-20  166  	    dphy_opts->hs_clk_rate < DATA_RATE_MIN_SPEED)
f4c8116e294b12c Guido Günther 2019-06-20  167  		return -EINVAL;
f4c8116e294b12c Guido Günther 2019-06-20  168  
f4c8116e294b12c Guido Günther 2019-06-20  169  	numerator = dphy_opts->hs_clk_rate;
f4c8116e294b12c Guido Günther 2019-06-20  170  	denominator = ref_clk;
f4c8116e294b12c Guido Günther 2019-06-20  171  	get_best_ratio(&numerator, &denominator, 255, 256);
f4c8116e294b12c Guido Günther 2019-06-20  172  	if (!numerator || !denominator) {
f4c8116e294b12c Guido Günther 2019-06-20  173  		dev_err(&phy->dev, "Invalid %d/%d for %ld/%ld\n",
f4c8116e294b12c Guido Günther 2019-06-20  174  			numerator, denominator,
f4c8116e294b12c Guido Günther 2019-06-20  175  			dphy_opts->hs_clk_rate, ref_clk);
f4c8116e294b12c Guido Günther 2019-06-20  176  		return -EINVAL;
f4c8116e294b12c Guido Günther 2019-06-20  177  	}
f4c8116e294b12c Guido Günther 2019-06-20  178  
f4c8116e294b12c Guido Günther 2019-06-20  179  	while ((numerator < 16) && (denominator <= 128)) {
f4c8116e294b12c Guido Günther 2019-06-20  180  		numerator <<= 1;
f4c8116e294b12c Guido Günther 2019-06-20  181  		denominator <<= 1;
f4c8116e294b12c Guido Günther 2019-06-20  182  	}
f4c8116e294b12c Guido Günther 2019-06-20  183  	/*
f4c8116e294b12c Guido Günther 2019-06-20  184  	 * CM ranges between 16 and 255
f4c8116e294b12c Guido Günther 2019-06-20  185  	 * CN ranges between 1 and 32
f4c8116e294b12c Guido Günther 2019-06-20  186  	 * CO is power of 2: 1, 2, 4, 8
f4c8116e294b12c Guido Günther 2019-06-20  187  	 */
f4c8116e294b12c Guido Günther 2019-06-20  188  	i = __ffs(denominator);
f4c8116e294b12c Guido Günther 2019-06-20  189  	if (i > 3)
f4c8116e294b12c Guido Günther 2019-06-20  190  		i = 3;
f4c8116e294b12c Guido Günther 2019-06-20  191  	cfg->cn = denominator >> i;
f4c8116e294b12c Guido Günther 2019-06-20  192  	cfg->co = 1 << i;
f4c8116e294b12c Guido Günther 2019-06-20  193  	cfg->cm = numerator;
f4c8116e294b12c Guido Günther 2019-06-20  194  
f4c8116e294b12c Guido Günther 2019-06-20  195  	if (cfg->cm < 16 || cfg->cm > 255 ||
f4c8116e294b12c Guido Günther 2019-06-20  196  	    cfg->cn < 1 || cfg->cn > 32 ||
f4c8116e294b12c Guido Günther 2019-06-20  197  	    cfg->co < 1 || cfg->co > 8) {
f4c8116e294b12c Guido Günther 2019-06-20  198  		dev_err(&phy->dev, "Invalid CM/CN/CO values: %u/%u/%u\n",
f4c8116e294b12c Guido Günther 2019-06-20  199  			cfg->cm, cfg->cn, cfg->co);
f4c8116e294b12c Guido Günther 2019-06-20  200  		dev_err(&phy->dev, "for hs_clk/ref_clk=%ld/%ld ~ %d/%d\n",
f4c8116e294b12c Guido Günther 2019-06-20  201  			dphy_opts->hs_clk_rate, ref_clk,
f4c8116e294b12c Guido Günther 2019-06-20  202  			numerator, denominator);
f4c8116e294b12c Guido Günther 2019-06-20  203  		return -EINVAL;
f4c8116e294b12c Guido Günther 2019-06-20  204  	}
f4c8116e294b12c Guido Günther 2019-06-20  205  
f4c8116e294b12c Guido Günther 2019-06-20  206  	dev_dbg(&phy->dev, "hs_clk/ref_clk=%ld/%ld ~ %d/%d\n",
f4c8116e294b12c Guido Günther 2019-06-20  207  		dphy_opts->hs_clk_rate, ref_clk, numerator, denominator);
f4c8116e294b12c Guido Günther 2019-06-20  208  
f4c8116e294b12c Guido Günther 2019-06-20  209  	/* LP clock period */
f4c8116e294b12c Guido Günther 2019-06-20  210  	tmp = 1000000000000LL;
f4c8116e294b12c Guido Günther 2019-06-20  211  	do_div(tmp, dphy_opts->lp_clk_rate); /* ps */
f4c8116e294b12c Guido Günther 2019-06-20  212  	if (tmp > ULONG_MAX)
f4c8116e294b12c Guido Günther 2019-06-20  213  		return -EINVAL;
f4c8116e294b12c Guido Günther 2019-06-20  214  
f4c8116e294b12c Guido Günther 2019-06-20  215  	lp_t = tmp;
f4c8116e294b12c Guido Günther 2019-06-20  216  	dev_dbg(&phy->dev, "LP clock %lu, period: %u ps\n",
f4c8116e294b12c Guido Günther 2019-06-20  217  		dphy_opts->lp_clk_rate, lp_t);
f4c8116e294b12c Guido Günther 2019-06-20  218  
f4c8116e294b12c Guido Günther 2019-06-20  219  	/* hs_prepare: in lp clock periods */
f4c8116e294b12c Guido Günther 2019-06-20  220  	if (2 * dphy_opts->hs_prepare > 5 * lp_t) {
f4c8116e294b12c Guido Günther 2019-06-20  221  		dev_err(&phy->dev,
f4c8116e294b12c Guido Günther 2019-06-20  222  			"hs_prepare (%u) > 2.5 * lp clock period (%u)\n",
f4c8116e294b12c Guido Günther 2019-06-20  223  			dphy_opts->hs_prepare, lp_t);
f4c8116e294b12c Guido Günther 2019-06-20  224  		return -EINVAL;
f4c8116e294b12c Guido Günther 2019-06-20  225  	}
f4c8116e294b12c Guido Günther 2019-06-20  226  	/* 00: lp_t, 01: 1.5 * lp_t, 10: 2 * lp_t, 11: 2.5 * lp_t */
f4c8116e294b12c Guido Günther 2019-06-20  227  	if (dphy_opts->hs_prepare < lp_t) {
f4c8116e294b12c Guido Günther 2019-06-20  228  		n = 0;
f4c8116e294b12c Guido Günther 2019-06-20  229  	} else {
f4c8116e294b12c Guido Günther 2019-06-20  230  		tmp = 2 * (dphy_opts->hs_prepare - lp_t);
f4c8116e294b12c Guido Günther 2019-06-20  231  		do_div(tmp, lp_t);
f4c8116e294b12c Guido Günther 2019-06-20  232  		n = tmp;
f4c8116e294b12c Guido Günther 2019-06-20  233  	}
f4c8116e294b12c Guido Günther 2019-06-20  234  	cfg->m_prg_hs_prepare = n;
f4c8116e294b12c Guido Günther 2019-06-20  235  
f4c8116e294b12c Guido Günther 2019-06-20  236  	/* clk_prepare: in lp clock periods */
f4c8116e294b12c Guido Günther 2019-06-20  237  	if (2 * dphy_opts->clk_prepare > 3 * lp_t) {
f4c8116e294b12c Guido Günther 2019-06-20  238  		dev_err(&phy->dev,
f4c8116e294b12c Guido Günther 2019-06-20  239  			"clk_prepare (%u) > 1.5 * lp clock period (%u)\n",
f4c8116e294b12c Guido Günther 2019-06-20  240  			dphy_opts->clk_prepare, lp_t);
f4c8116e294b12c Guido Günther 2019-06-20  241  		return -EINVAL;
f4c8116e294b12c Guido Günther 2019-06-20  242  	}
f4c8116e294b12c Guido Günther 2019-06-20  243  	/* 00: lp_t, 01: 1.5 * lp_t */
f4c8116e294b12c Guido Günther 2019-06-20  244  	cfg->mc_prg_hs_prepare = dphy_opts->clk_prepare > lp_t ? 1 : 0;
f4c8116e294b12c Guido Günther 2019-06-20  245  
f4c8116e294b12c Guido Günther 2019-06-20  246  	/* hs_zero: formula from NXP BSP */
f4c8116e294b12c Guido Günther 2019-06-20  247  	n = (144 * (dphy_opts->hs_clk_rate / 1000000) - 47500) / 10000;
f4c8116e294b12c Guido Günther 2019-06-20  248  	cfg->m_prg_hs_zero = n < 1 ? 1 : n;
f4c8116e294b12c Guido Günther 2019-06-20  249  
f4c8116e294b12c Guido Günther 2019-06-20  250  	/* clk_zero: formula from NXP BSP */
f4c8116e294b12c Guido Günther 2019-06-20  251  	n = (34 * (dphy_opts->hs_clk_rate / 1000000) - 2500) / 1000;
f4c8116e294b12c Guido Günther 2019-06-20  252  	cfg->mc_prg_hs_zero = n < 1 ? 1 : n;
f4c8116e294b12c Guido Günther 2019-06-20  253  
f4c8116e294b12c Guido Günther 2019-06-20  254  	/* clk_trail, hs_trail: formula from NXP BSP */
f4c8116e294b12c Guido Günther 2019-06-20  255  	n = (103 * (dphy_opts->hs_clk_rate / 1000000) + 10000) / 10000;
f4c8116e294b12c Guido Günther 2019-06-20  256  	if (n > 15)
f4c8116e294b12c Guido Günther 2019-06-20  257  		n = 15;
f4c8116e294b12c Guido Günther 2019-06-20  258  	if (n < 1)
f4c8116e294b12c Guido Günther 2019-06-20  259  		n = 1;
f4c8116e294b12c Guido Günther 2019-06-20  260  	cfg->m_prg_hs_trail = n;
f4c8116e294b12c Guido Günther 2019-06-20  261  	cfg->mc_prg_hs_trail = n;
f4c8116e294b12c Guido Günther 2019-06-20  262  
f4c8116e294b12c Guido Günther 2019-06-20  263  	/* rxhs_settle: formula from NXP BSP */
f4c8116e294b12c Guido Günther 2019-06-20  264  	if (dphy_opts->hs_clk_rate < MBPS(80))
f4c8116e294b12c Guido Günther 2019-06-20  265  		cfg->rxhs_settle = 0x0d;
f4c8116e294b12c Guido Günther 2019-06-20  266  	else if (dphy_opts->hs_clk_rate < MBPS(90))
f4c8116e294b12c Guido Günther 2019-06-20  267  		cfg->rxhs_settle = 0x0c;
f4c8116e294b12c Guido Günther 2019-06-20  268  	else if (dphy_opts->hs_clk_rate < MBPS(125))
f4c8116e294b12c Guido Günther 2019-06-20  269  		cfg->rxhs_settle = 0x0b;
f4c8116e294b12c Guido Günther 2019-06-20  270  	else if (dphy_opts->hs_clk_rate < MBPS(150))
f4c8116e294b12c Guido Günther 2019-06-20  271  		cfg->rxhs_settle = 0x0a;
f4c8116e294b12c Guido Günther 2019-06-20  272  	else if (dphy_opts->hs_clk_rate < MBPS(225))
f4c8116e294b12c Guido Günther 2019-06-20  273  		cfg->rxhs_settle = 0x09;
f4c8116e294b12c Guido Günther 2019-06-20  274  	else if (dphy_opts->hs_clk_rate < MBPS(500))
f4c8116e294b12c Guido Günther 2019-06-20  275  		cfg->rxhs_settle = 0x08;
f4c8116e294b12c Guido Günther 2019-06-20  276  	else
f4c8116e294b12c Guido Günther 2019-06-20  277  		cfg->rxhs_settle = 0x07;
f4c8116e294b12c Guido Günther 2019-06-20  278  
f4c8116e294b12c Guido Günther 2019-06-20  279  	dev_dbg(&phy->dev, "phy_config: %u %u %u %u %u %u %u\n",
f4c8116e294b12c Guido Günther 2019-06-20  280  		cfg->m_prg_hs_prepare, cfg->mc_prg_hs_prepare,
f4c8116e294b12c Guido Günther 2019-06-20  281  		cfg->m_prg_hs_zero, cfg->mc_prg_hs_zero,
f4c8116e294b12c Guido Günther 2019-06-20  282  		cfg->m_prg_hs_trail, cfg->mc_prg_hs_trail,
f4c8116e294b12c Guido Günther 2019-06-20  283  		cfg->rxhs_settle);
f4c8116e294b12c Guido Günther 2019-06-20  284  
f4c8116e294b12c Guido Günther 2019-06-20  285  	return 0;
f4c8116e294b12c Guido Günther 2019-06-20  286  }
f4c8116e294b12c Guido Günther 2019-06-20  287  
f4c8116e294b12c Guido Günther 2019-06-20  288  static void mixel_phy_set_hs_timings(struct phy *phy)
f4c8116e294b12c Guido Günther 2019-06-20  289  {
f4c8116e294b12c Guido Günther 2019-06-20  290  	struct mixel_dphy_priv *priv = phy_get_drvdata(phy);
f4c8116e294b12c Guido Günther 2019-06-20  291  
f4c8116e294b12c Guido Günther 2019-06-20  292  	phy_write(phy, priv->cfg.m_prg_hs_prepare, DPHY_M_PRG_HS_PREPARE);
f4c8116e294b12c Guido Günther 2019-06-20  293  	phy_write(phy, priv->cfg.mc_prg_hs_prepare, DPHY_MC_PRG_HS_PREPARE);
f4c8116e294b12c Guido Günther 2019-06-20  294  	phy_write(phy, priv->cfg.m_prg_hs_zero, DPHY_M_PRG_HS_ZERO);
f4c8116e294b12c Guido Günther 2019-06-20  295  	phy_write(phy, priv->cfg.mc_prg_hs_zero, DPHY_MC_PRG_HS_ZERO);
f4c8116e294b12c Guido Günther 2019-06-20  296  	phy_write(phy, priv->cfg.m_prg_hs_trail, DPHY_M_PRG_HS_TRAIL);
f4c8116e294b12c Guido Günther 2019-06-20  297  	phy_write(phy, priv->cfg.mc_prg_hs_trail, DPHY_MC_PRG_HS_TRAIL);
f4c8116e294b12c Guido Günther 2019-06-20  298  	phy_write(phy, priv->cfg.rxhs_settle, priv->devdata->reg_rxhs_settle);
f4c8116e294b12c Guido Günther 2019-06-20  299  }
f4c8116e294b12c Guido Günther 2019-06-20  300  
f4c8116e294b12c Guido Günther 2019-06-20  301  static int mixel_dphy_set_pll_params(struct phy *phy)
f4c8116e294b12c Guido Günther 2019-06-20  302  {
f4c8116e294b12c Guido Günther 2019-06-20  303  	struct mixel_dphy_priv *priv = dev_get_drvdata(phy->dev.parent);
f4c8116e294b12c Guido Günther 2019-06-20  304  
f4c8116e294b12c Guido Günther 2019-06-20  305  	if (priv->cfg.cm < 16 || priv->cfg.cm > 255 ||
f4c8116e294b12c Guido Günther 2019-06-20  306  	    priv->cfg.cn < 1 || priv->cfg.cn > 32 ||
f4c8116e294b12c Guido Günther 2019-06-20  307  	    priv->cfg.co < 1 || priv->cfg.co > 8) {
f4c8116e294b12c Guido Günther 2019-06-20  308  		dev_err(&phy->dev, "Invalid CM/CN/CO values! (%u/%u/%u)\n",
f4c8116e294b12c Guido Günther 2019-06-20  309  			priv->cfg.cm, priv->cfg.cn, priv->cfg.co);
f4c8116e294b12c Guido Günther 2019-06-20  310  		return -EINVAL;
f4c8116e294b12c Guido Günther 2019-06-20  311  	}
f4c8116e294b12c Guido Günther 2019-06-20  312  	dev_dbg(&phy->dev, "Using CM:%u CN:%u CO:%u\n",
f4c8116e294b12c Guido Günther 2019-06-20  313  		priv->cfg.cm, priv->cfg.cn, priv->cfg.co);
f4c8116e294b12c Guido Günther 2019-06-20  314  	phy_write(phy, CM(priv->cfg.cm), DPHY_CM);
f4c8116e294b12c Guido Günther 2019-06-20  315  	phy_write(phy, CN(priv->cfg.cn), DPHY_CN);
f4c8116e294b12c Guido Günther 2019-06-20  316  	phy_write(phy, CO(priv->cfg.co), DPHY_CO);
f4c8116e294b12c Guido Günther 2019-06-20  317  	return 0;
f4c8116e294b12c Guido Günther 2019-06-20  318  }
f4c8116e294b12c Guido Günther 2019-06-20  319  
f4c8116e294b12c Guido Günther 2019-06-20  320  static int mixel_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
f4c8116e294b12c Guido Günther 2019-06-20  321  {
f4c8116e294b12c Guido Günther 2019-06-20  322  	struct mixel_dphy_priv *priv = phy_get_drvdata(phy);
f4c8116e294b12c Guido Günther 2019-06-20  323  	struct mixel_dphy_cfg cfg = { 0 };
f4c8116e294b12c Guido Günther 2019-06-20  324  	int ret;
f4c8116e294b12c Guido Günther 2019-06-20  325  
f4c8116e294b12c Guido Günther 2019-06-20 @326  	ret = mixel_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
f4c8116e294b12c Guido Günther 2019-06-20  327  	if (ret)
f4c8116e294b12c Guido Günther 2019-06-20  328  		return ret;
f4c8116e294b12c Guido Günther 2019-06-20  329  
f4c8116e294b12c Guido Günther 2019-06-20  330  	/* Update the configuration */
f4c8116e294b12c Guido Günther 2019-06-20  331  	memcpy(&priv->cfg, &cfg, sizeof(struct mixel_dphy_cfg));
f4c8116e294b12c Guido Günther 2019-06-20  332  
f4c8116e294b12c Guido Günther 2019-06-20  333  	phy_write(phy, 0x00, DPHY_LOCK_BYP);
f4c8116e294b12c Guido Günther 2019-06-20  334  	phy_write(phy, 0x01, priv->devdata->reg_tx_rcal);
f4c8116e294b12c Guido Günther 2019-06-20  335  	phy_write(phy, 0x00, priv->devdata->reg_auto_pd_en);
f4c8116e294b12c Guido Günther 2019-06-20  336  	phy_write(phy, 0x02, priv->devdata->reg_rxlprp);
f4c8116e294b12c Guido Günther 2019-06-20  337  	phy_write(phy, 0x02, priv->devdata->reg_rxcdrp);
f4c8116e294b12c Guido Günther 2019-06-20  338  	phy_write(phy, 0x25, DPHY_TST);
f4c8116e294b12c Guido Günther 2019-06-20  339  
f4c8116e294b12c Guido Günther 2019-06-20  340  	mixel_phy_set_hs_timings(phy);
f4c8116e294b12c Guido Günther 2019-06-20  341  	ret = mixel_dphy_set_pll_params(phy);
f4c8116e294b12c Guido Günther 2019-06-20  342  	if (ret < 0)
f4c8116e294b12c Guido Günther 2019-06-20  343  		return ret;
f4c8116e294b12c Guido Günther 2019-06-20  344  
f4c8116e294b12c Guido Günther 2019-06-20  345  	return 0;
f4c8116e294b12c Guido Günther 2019-06-20  346  }
f4c8116e294b12c Guido Günther 2019-06-20  347  
f4c8116e294b12c Guido Günther 2019-06-20  348  static int mixel_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
f4c8116e294b12c Guido Günther 2019-06-20 @349  			       union phy_configure_opts *opts)
f4c8116e294b12c Guido Günther 2019-06-20  350  {
f4c8116e294b12c Guido Günther 2019-06-20  351  	struct mixel_dphy_cfg cfg = { 0 };
f4c8116e294b12c Guido Günther 2019-06-20  352  
f4c8116e294b12c Guido Günther 2019-06-20  353  	if (mode != PHY_MODE_MIPI_DPHY)
f4c8116e294b12c Guido Günther 2019-06-20  354  		return -EINVAL;
f4c8116e294b12c Guido Günther 2019-06-20  355  
f4c8116e294b12c Guido Günther 2019-06-20  356  	return mixel_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
f4c8116e294b12c Guido Günther 2019-06-20  357  }
f4c8116e294b12c Guido Günther 2019-06-20  358  
f4c8116e294b12c Guido Günther 2019-06-20  359  static int mixel_dphy_init(struct phy *phy)
f4c8116e294b12c Guido Günther 2019-06-20  360  {
f4c8116e294b12c Guido Günther 2019-06-20  361  	phy_write(phy, PWR_OFF, DPHY_PD_PLL);
f4c8116e294b12c Guido Günther 2019-06-20  362  	phy_write(phy, PWR_OFF, DPHY_PD_DPHY);
f4c8116e294b12c Guido Günther 2019-06-20  363  
f4c8116e294b12c Guido Günther 2019-06-20  364  	return 0;
f4c8116e294b12c Guido Günther 2019-06-20  365  }
f4c8116e294b12c Guido Günther 2019-06-20  366  
f4c8116e294b12c Guido Günther 2019-06-20  367  static int mixel_dphy_exit(struct phy *phy)
f4c8116e294b12c Guido Günther 2019-06-20  368  {
f4c8116e294b12c Guido Günther 2019-06-20  369  	phy_write(phy, 0, DPHY_CM);
f4c8116e294b12c Guido Günther 2019-06-20  370  	phy_write(phy, 0, DPHY_CN);
f4c8116e294b12c Guido Günther 2019-06-20  371  	phy_write(phy, 0, DPHY_CO);
f4c8116e294b12c Guido Günther 2019-06-20  372  
f4c8116e294b12c Guido Günther 2019-06-20  373  	return 0;
f4c8116e294b12c Guido Günther 2019-06-20  374  }
f4c8116e294b12c Guido Günther 2019-06-20  375  
f4c8116e294b12c Guido Günther 2019-06-20  376  static int mixel_dphy_power_on(struct phy *phy)
f4c8116e294b12c Guido Günther 2019-06-20  377  {
f4c8116e294b12c Guido Günther 2019-06-20  378  	struct mixel_dphy_priv *priv = phy_get_drvdata(phy);
f4c8116e294b12c Guido Günther 2019-06-20  379  	u32 locked;
f4c8116e294b12c Guido Günther 2019-06-20  380  	int ret;
f4c8116e294b12c Guido Günther 2019-06-20  381  
f4c8116e294b12c Guido Günther 2019-06-20  382  	ret = clk_prepare_enable(priv->phy_ref_clk);
f4c8116e294b12c Guido Günther 2019-06-20  383  	if (ret < 0)
f4c8116e294b12c Guido Günther 2019-06-20  384  		return ret;
f4c8116e294b12c Guido Günther 2019-06-20  385  
f4c8116e294b12c Guido Günther 2019-06-20  386  	phy_write(phy, PWR_ON, DPHY_PD_PLL);
f4c8116e294b12c Guido Günther 2019-06-20  387  	ret = regmap_read_poll_timeout(priv->regmap, DPHY_LOCK, locked,
f4c8116e294b12c Guido Günther 2019-06-20  388  				       locked, PLL_LOCK_SLEEP,
f4c8116e294b12c Guido Günther 2019-06-20  389  				       PLL_LOCK_TIMEOUT);
f4c8116e294b12c Guido Günther 2019-06-20  390  	if (ret < 0) {
f4c8116e294b12c Guido Günther 2019-06-20  391  		dev_err(&phy->dev, "Could not get DPHY lock (%d)!\n", ret);
f4c8116e294b12c Guido Günther 2019-06-20  392  		goto clock_disable;
f4c8116e294b12c Guido Günther 2019-06-20  393  	}
f4c8116e294b12c Guido Günther 2019-06-20  394  	phy_write(phy, PWR_ON, DPHY_PD_DPHY);
f4c8116e294b12c Guido Günther 2019-06-20  395  
f4c8116e294b12c Guido Günther 2019-06-20  396  	return 0;
f4c8116e294b12c Guido Günther 2019-06-20  397  clock_disable:
f4c8116e294b12c Guido Günther 2019-06-20  398  	clk_disable_unprepare(priv->phy_ref_clk);
f4c8116e294b12c Guido Günther 2019-06-20  399  	return ret;
f4c8116e294b12c Guido Günther 2019-06-20  400  }
f4c8116e294b12c Guido Günther 2019-06-20  401  
f4c8116e294b12c Guido Günther 2019-06-20  402  static int mixel_dphy_power_off(struct phy *phy)
f4c8116e294b12c Guido Günther 2019-06-20  403  {
f4c8116e294b12c Guido Günther 2019-06-20  404  	struct mixel_dphy_priv *priv = phy_get_drvdata(phy);
f4c8116e294b12c Guido Günther 2019-06-20  405  
f4c8116e294b12c Guido Günther 2019-06-20  406  	phy_write(phy, PWR_OFF, DPHY_PD_PLL);
f4c8116e294b12c Guido Günther 2019-06-20  407  	phy_write(phy, PWR_OFF, DPHY_PD_DPHY);
f4c8116e294b12c Guido Günther 2019-06-20  408  
f4c8116e294b12c Guido Günther 2019-06-20  409  	clk_disable_unprepare(priv->phy_ref_clk);
f4c8116e294b12c Guido Günther 2019-06-20  410  
f4c8116e294b12c Guido Günther 2019-06-20  411  	return 0;
f4c8116e294b12c Guido Günther 2019-06-20  412  }
f4c8116e294b12c Guido Günther 2019-06-20  413  
f4c8116e294b12c Guido Günther 2019-06-20  414  static const struct phy_ops mixel_dphy_phy_ops = {
f4c8116e294b12c Guido Günther 2019-06-20  415  	.init = mixel_dphy_init,
f4c8116e294b12c Guido Günther 2019-06-20  416  	.exit = mixel_dphy_exit,
f4c8116e294b12c Guido Günther 2019-06-20  417  	.power_on = mixel_dphy_power_on,
f4c8116e294b12c Guido Günther 2019-06-20  418  	.power_off = mixel_dphy_power_off,
f4c8116e294b12c Guido Günther 2019-06-20  419  	.configure = mixel_dphy_configure,
f4c8116e294b12c Guido Günther 2019-06-20  420  	.validate = mixel_dphy_validate,
f4c8116e294b12c Guido Günther 2019-06-20  421  	.owner = THIS_MODULE,
f4c8116e294b12c Guido Günther 2019-06-20  422  };
f4c8116e294b12c Guido Günther 2019-06-20  423  
f4c8116e294b12c Guido Günther 2019-06-20  424  static const struct of_device_id mixel_dphy_of_match[] = {
f4c8116e294b12c Guido Günther 2019-06-20  425  	{ .compatible = "fsl,imx8mq-mipi-dphy",
f4c8116e294b12c Guido Günther 2019-06-20  426  	  .data = &mixel_dphy_devdata[MIXEL_IMX8MQ] },
f4c8116e294b12c Guido Günther 2019-06-20  427  	{ /* sentinel */ },
f4c8116e294b12c Guido Günther 2019-06-20  428  };
f4c8116e294b12c Guido Günther 2019-06-20  429  MODULE_DEVICE_TABLE(of, mixel_dphy_of_match);
f4c8116e294b12c Guido Günther 2019-06-20  430  
f4c8116e294b12c Guido Günther 2019-06-20  431  static int mixel_dphy_probe(struct platform_device *pdev)
f4c8116e294b12c Guido Günther 2019-06-20  432  {
f4c8116e294b12c Guido Günther 2019-06-20  433  	struct device *dev = &pdev->dev;
f4c8116e294b12c Guido Günther 2019-06-20  434  	struct device_node *np = dev->of_node;
f4c8116e294b12c Guido Günther 2019-06-20  435  	struct phy_provider *phy_provider;
f4c8116e294b12c Guido Günther 2019-06-20  436  	struct mixel_dphy_priv *priv;
f4c8116e294b12c Guido Günther 2019-06-20  437  	struct resource *res;
f4c8116e294b12c Guido Günther 2019-06-20  438  	struct phy *phy;
f4c8116e294b12c Guido Günther 2019-06-20  439  	void __iomem *base;
f4c8116e294b12c Guido Günther 2019-06-20  440  
f4c8116e294b12c Guido Günther 2019-06-20  441  	if (!np)
f4c8116e294b12c Guido Günther 2019-06-20  442  		return -ENODEV;
f4c8116e294b12c Guido Günther 2019-06-20  443  
f4c8116e294b12c Guido Günther 2019-06-20  444  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
f4c8116e294b12c Guido Günther 2019-06-20  445  	if (!priv)
f4c8116e294b12c Guido Günther 2019-06-20  446  		return -ENOMEM;
f4c8116e294b12c Guido Günther 2019-06-20  447  
f4c8116e294b12c Guido Günther 2019-06-20  448  	priv->devdata = of_device_get_match_data(&pdev->dev);
f4c8116e294b12c Guido Günther 2019-06-20  449  	if (!priv->devdata)
f4c8116e294b12c Guido Günther 2019-06-20  450  		return -EINVAL;
f4c8116e294b12c Guido Günther 2019-06-20  451  
f4c8116e294b12c Guido Günther 2019-06-20  452  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
f4c8116e294b12c Guido Günther 2019-06-20  453  	base = devm_ioremap_resource(dev, res);
f4c8116e294b12c Guido Günther 2019-06-20  454  	if (IS_ERR(base))
f4c8116e294b12c Guido Günther 2019-06-20  455  		return PTR_ERR(base);
f4c8116e294b12c Guido Günther 2019-06-20  456  
f4c8116e294b12c Guido Günther 2019-06-20  457  	priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
f4c8116e294b12c Guido Günther 2019-06-20  458  					     &mixel_dphy_regmap_config);
f4c8116e294b12c Guido Günther 2019-06-20  459  	if (IS_ERR(priv->regmap)) {
f4c8116e294b12c Guido Günther 2019-06-20  460  		dev_err(dev, "Couldn't create the DPHY regmap\n");
f4c8116e294b12c Guido Günther 2019-06-20  461  		return PTR_ERR(priv->regmap);
f4c8116e294b12c Guido Günther 2019-06-20  462  	}
f4c8116e294b12c Guido Günther 2019-06-20  463  
f4c8116e294b12c Guido Günther 2019-06-20  464  	priv->phy_ref_clk = devm_clk_get(&pdev->dev, "phy_ref");
f4c8116e294b12c Guido Günther 2019-06-20  465  	if (IS_ERR(priv->phy_ref_clk)) {
f4c8116e294b12c Guido Günther 2019-06-20  466  		dev_err(dev, "No phy_ref clock found\n");
f4c8116e294b12c Guido Günther 2019-06-20  467  		return PTR_ERR(priv->phy_ref_clk);
f4c8116e294b12c Guido Günther 2019-06-20  468  	}
f4c8116e294b12c Guido Günther 2019-06-20  469  	dev_dbg(dev, "phy_ref clock rate: %lu\n",
f4c8116e294b12c Guido Günther 2019-06-20  470  		clk_get_rate(priv->phy_ref_clk));
f4c8116e294b12c Guido Günther 2019-06-20  471  
f4c8116e294b12c Guido Günther 2019-06-20  472  	dev_set_drvdata(dev, priv);
f4c8116e294b12c Guido Günther 2019-06-20  473  
f4c8116e294b12c Guido Günther 2019-06-20  474  	phy = devm_phy_create(dev, np, &mixel_dphy_phy_ops);
f4c8116e294b12c Guido Günther 2019-06-20  475  	if (IS_ERR(phy)) {
f4c8116e294b12c Guido Günther 2019-06-20  476  		dev_err(dev, "Failed to create phy %ld\n", PTR_ERR(phy));
f4c8116e294b12c Guido Günther 2019-06-20  477  		return PTR_ERR(phy);
f4c8116e294b12c Guido Günther 2019-06-20  478  	}
f4c8116e294b12c Guido Günther 2019-06-20  479  	phy_set_drvdata(phy, priv);
f4c8116e294b12c Guido Günther 2019-06-20  480  
f4c8116e294b12c Guido Günther 2019-06-20  481  	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
f4c8116e294b12c Guido Günther 2019-06-20  482  
f4c8116e294b12c Guido Günther 2019-06-20  483  	return PTR_ERR_OR_ZERO(phy_provider);
f4c8116e294b12c Guido Günther 2019-06-20  484  }
f4c8116e294b12c Guido Günther 2019-06-20  485  
f4c8116e294b12c Guido Günther 2019-06-20  486  static struct platform_driver mixel_dphy_driver = {
f4c8116e294b12c Guido Günther 2019-06-20  487  	.probe	= mixel_dphy_probe,
f4c8116e294b12c Guido Günther 2019-06-20  488  	.driver = {
f4c8116e294b12c Guido Günther 2019-06-20  489  		.name = "mixel-mipi-dphy",
f4c8116e294b12c Guido Günther 2019-06-20  490  		.of_match_table	= mixel_dphy_of_match,
f4c8116e294b12c Guido Günther 2019-06-20  491  	}
f4c8116e294b12c Guido Günther 2019-06-20  492  };
f4c8116e294b12c Guido Günther 2019-06-20  493  module_platform_driver(mixel_dphy_driver);
f4c8116e294b12c Guido Günther 2019-06-20  494  
f4c8116e294b12c Guido Günther 2019-06-20  495  MODULE_AUTHOR("NXP Semiconductor");
f4c8116e294b12c Guido Günther 2019-06-20  496  MODULE_DESCRIPTION("Mixel MIPI-DSI PHY driver");
f4c8116e294b12c Guido Günther 2019-06-20  497  MODULE_LICENSE("GPL");

:::::: The code at line 165 was first introduced by commit
:::::: f4c8116e294b12c360b724173f4b79f232573fb1 phy: Add driver for mixel mipi dphy found on NXP's i.MX8 SoCs

:::::: TO: Guido Günther <agx@...xcpu.org>
:::::: CC: Kishon Vijay Abraham I <kishon@...com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Download attachment ".config.gz" of type "application/gzip" (66052 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ