Re: [PATCH] phy: Change the configuration interface param to void* to make it more general

From: kbuild test robot
Date: Sat Jul 13 2019 - 19:21:59 EST


Hi Zeng,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[cannot apply to v5.2 next-20190712]
[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: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-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=arm

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

All warnings (new ones prefixed by >>):

>> 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
--
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]

vim +155 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 155 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@xxxxxxxxxxx>
:::::: CC: Kishon Vijay Abraham I <kishon@xxxxxx>

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

Attachment: .config.gz
Description: application/gzip