* Re: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1
@ 2025-06-04 16:42 ` Dan Carpenter
0 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2025-06-04 15:45 UTC (permalink / raw)
To: oe-kbuild; +Cc: lkp, Dan Carpenter
BCC: lkp@intel.com
CC: oe-kbuild-all@lists.linux.dev
In-Reply-To: <20250523083655.3876005-3-y-abhilashchandra@ti.com>
References: <20250523083655.3876005-3-y-abhilashchandra@ti.com>
TO: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
TO: tomi.valkeinen@ideasonboard.com
TO: mchehab@kernel.org
TO: robh@kernel.org
TO: krzk+dt@kernel.org
TO: conor+dt@kernel.org
CC: hverkuil@xs4all.nl
CC: sakari.ailus@linux.intel.com
CC: laurent.pinchart@ideasonboard.com
CC: vaishnav.a@ti.com
CC: u-kumar1@ti.com
CC: jai.luthra@linux.dev
CC: linux-media@vger.kernel.org
CC: devicetree@vger.kernel.org
CC: linux-kernel@vger.kernel.org
CC: y-abhilashchandra@ti.com
Hi Yemike,
kernel test robot noticed the following build warnings:
[auto build test WARNING on linuxtv-media-pending/master]
[also build test WARNING on linus/master next-20250604]
[cannot apply to robh/for-next v6.15]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Yemike-Abhilash-Chandra/media-dt-bindings-ti-ds90ub960-Add-bindings-for-DS90UB954-Q1/20250523-164041
base: https://git.linuxtv.org/media-ci/media-pending.git master
patch link: https://lore.kernel.org/r/20250523083655.3876005-3-y-abhilashchandra%40ti.com
patch subject: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1
:::::: branch date: 12 days ago
:::::: commit date: 12 days ago
config: arc-randconfig-r071-20250604 (https://download.01.org/0day-ci/archive/20250604/202506042333.FlFAp4mW-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 15.1.0
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Closes: https://lore.kernel.org/r/202506042333.FlFAp4mW-lkp@intel.com/
smatch warnings:
drivers/media/i2c/ds90ub960.c:5046 ub960_enable_core_hw() error: uninitialized symbol 'refclk_freq'.
vim +/refclk_freq +5046 drivers/media/i2c/ds90ub960.c
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4980
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4981 static int ub960_enable_core_hw(struct ub960_data *priv)
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4982 {
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4983 struct device *dev = &priv->client->dev;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4984 u8 rev_mask;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4985 int ret;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4986 u8 dev_sts;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4987 u8 refclk_freq;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4988
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4989 ret = regulator_enable(priv->vddio);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4990 if (ret)
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4991 return dev_err_probe(dev, ret,
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4992 "failed to enable VDDIO regulator\n");
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4993
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4994 ret = clk_prepare_enable(priv->refclk);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4995 if (ret) {
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4996 dev_err_probe(dev, ret, "Failed to enable refclk\n");
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4997 goto err_disable_vddio;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4998 }
afe267f2d368f5 Tomi Valkeinen 2023-06-19 4999
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5000 if (priv->pd_gpio) {
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5001 gpiod_set_value_cansleep(priv->pd_gpio, 1);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5002 /* wait min 2 ms for reset to complete */
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5003 fsleep(2000);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5004 gpiod_set_value_cansleep(priv->pd_gpio, 0);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5005 /* wait min 2 ms for power up to finish */
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5006 fsleep(2000);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5007 }
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5008
8f512c3113756c Tomi Valkeinen 2025-03-03 5009 ret = ub960_reset(priv, true);
8f512c3113756c Tomi Valkeinen 2025-03-03 5010 if (ret)
8f512c3113756c Tomi Valkeinen 2025-03-03 5011 goto err_pd_gpio;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5012
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5013 /* Runtime check register accessibility */
24868501a74402 Tomi Valkeinen 2025-03-03 5014 ret = ub960_read(priv, UB960_SR_REV_MASK, &rev_mask, NULL);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5015 if (ret) {
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5016 dev_err_probe(dev, ret, "Cannot read first register, abort\n");
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5017 goto err_pd_gpio;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5018 }
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5019
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5020 dev_dbg(dev, "Found %s (rev/mask %#04x)\n", priv->hw_data->model,
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5021 rev_mask);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5022
24868501a74402 Tomi Valkeinen 2025-03-03 5023 ret = ub960_read(priv, UB960_SR_DEVICE_STS, &dev_sts, NULL);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5024 if (ret)
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5025 goto err_pd_gpio;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5026
ba3bdb93947c90 Tomi Valkeinen 2024-12-06 5027 if (priv->hw_data->is_ub9702)
24868501a74402 Tomi Valkeinen 2025-03-03 5028 ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq,
24868501a74402 Tomi Valkeinen 2025-03-03 5029 NULL);
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5030 else if (priv->hw_data->is_ub954) {
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5031 /* From DS90UB954-Q1 datasheet:
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5032 * "REFCLK_FREQ measurement is not synchronized. Value in this
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5033 * register should read twice and only considered valid if
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5034 * REFCLK_FREQ is unchanged between reads."
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5035 */
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5036 unsigned long timeout = jiffies + msecs_to_jiffies(100);
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5037
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5038 do {
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5039 u8 refclk_new;
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5040
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5041 ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_new,
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5042 NULL);
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5043 if (ret)
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5044 goto err_pd_gpio;
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5045
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 @5046 if (refclk_new == refclk_freq)
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5047 break;
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5048 refclk_freq = refclk_new;
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5049 } while (time_before(jiffies, timeout));
8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5050 }
ba3bdb93947c90 Tomi Valkeinen 2024-12-06 5051 else
24868501a74402 Tomi Valkeinen 2025-03-03 5052 ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq,
24868501a74402 Tomi Valkeinen 2025-03-03 5053 NULL);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5054 if (ret)
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5055 goto err_pd_gpio;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5056
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5057 dev_dbg(dev, "refclk valid %u freq %u MHz (clk fw freq %lu MHz)\n",
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5058 !!(dev_sts & BIT(4)), refclk_freq,
a56fac44beced4 Tomi Valkeinen 2024-12-06 5059 clk_get_rate(priv->refclk) / HZ_PER_MHZ);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5060
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5061 /* Disable all RX ports by default */
24868501a74402 Tomi Valkeinen 2025-03-03 5062 ret = ub960_write(priv, UB960_SR_RX_PORT_CTL, 0, NULL);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5063 if (ret)
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5064 goto err_pd_gpio;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5065
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5066 /* release GPIO lock */
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5067 if (priv->hw_data->is_ub9702) {
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5068 ret = ub960_update_bits(priv, UB960_SR_RESET,
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5069 UB960_SR_RESET_GPIO_LOCK_RELEASE,
24868501a74402 Tomi Valkeinen 2025-03-03 5070 UB960_SR_RESET_GPIO_LOCK_RELEASE,
24868501a74402 Tomi Valkeinen 2025-03-03 5071 NULL);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5072 if (ret)
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5073 goto err_pd_gpio;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5074 }
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5075
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5076 return 0;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5077
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5078 err_pd_gpio:
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5079 gpiod_set_value_cansleep(priv->pd_gpio, 1);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5080 clk_disable_unprepare(priv->refclk);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5081 err_disable_vddio:
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5082 regulator_disable(priv->vddio);
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5083
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5084 return ret;
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5085 }
afe267f2d368f5 Tomi Valkeinen 2023-06-19 5086
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 @ 2025-06-04 16:42 ` Dan Carpenter 0 siblings, 0 replies; 9+ messages in thread From: Dan Carpenter @ 2025-06-04 16:42 UTC (permalink / raw) To: oe-kbuild; +Cc: lkp BCC: lkp@intel.com CC: oe-kbuild-all@lists.linux.dev In-Reply-To: <20250523083655.3876005-3-y-abhilashchandra@ti.com> References: <20250523083655.3876005-3-y-abhilashchandra@ti.com> TO: Yemike Abhilash Chandra <y-abhilashchandra@ti.com> TO: tomi.valkeinen@ideasonboard.com TO: mchehab@kernel.org TO: robh@kernel.org TO: krzk+dt@kernel.org TO: conor+dt@kernel.org CC: hverkuil@xs4all.nl CC: sakari.ailus@linux.intel.com CC: laurent.pinchart@ideasonboard.com CC: vaishnav.a@ti.com CC: u-kumar1@ti.com CC: jai.luthra@linux.dev CC: linux-media@vger.kernel.org CC: devicetree@vger.kernel.org CC: linux-kernel@vger.kernel.org CC: y-abhilashchandra@ti.com Hi Yemike, kernel test robot noticed the following build warnings: https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Yemike-Abhilash-Chandra/media-dt-bindings-ti-ds90ub960-Add-bindings-for-DS90UB954-Q1/20250523-164041 base: https://git.linuxtv.org/media-ci/media-pending.git master patch link: https://lore.kernel.org/r/20250523083655.3876005-3-y-abhilashchandra%40ti.com patch subject: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 config: arc-randconfig-r071-20250604 (https://download.01.org/0day-ci/archive/20250604/202506042333.FlFAp4mW-lkp@intel.com/config) compiler: arc-linux-gcc (GCC) 15.1.0 If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> | Closes: https://lore.kernel.org/r/202506042333.FlFAp4mW-lkp@intel.com/ smatch warnings: drivers/media/i2c/ds90ub960.c:5046 ub960_enable_core_hw() error: uninitialized symbol 'refclk_freq'. vim +/refclk_freq +5046 drivers/media/i2c/ds90ub960.c afe267f2d368f5 Tomi Valkeinen 2023-06-19 4981 static int ub960_enable_core_hw(struct ub960_data *priv) afe267f2d368f5 Tomi Valkeinen 2023-06-19 4982 { afe267f2d368f5 Tomi Valkeinen 2023-06-19 4983 struct device *dev = &priv->client->dev; afe267f2d368f5 Tomi Valkeinen 2023-06-19 4984 u8 rev_mask; afe267f2d368f5 Tomi Valkeinen 2023-06-19 4985 int ret; afe267f2d368f5 Tomi Valkeinen 2023-06-19 4986 u8 dev_sts; afe267f2d368f5 Tomi Valkeinen 2023-06-19 4987 u8 refclk_freq; afe267f2d368f5 Tomi Valkeinen 2023-06-19 4988 afe267f2d368f5 Tomi Valkeinen 2023-06-19 4989 ret = regulator_enable(priv->vddio); afe267f2d368f5 Tomi Valkeinen 2023-06-19 4990 if (ret) afe267f2d368f5 Tomi Valkeinen 2023-06-19 4991 return dev_err_probe(dev, ret, afe267f2d368f5 Tomi Valkeinen 2023-06-19 4992 "failed to enable VDDIO regulator\n"); afe267f2d368f5 Tomi Valkeinen 2023-06-19 4993 afe267f2d368f5 Tomi Valkeinen 2023-06-19 4994 ret = clk_prepare_enable(priv->refclk); afe267f2d368f5 Tomi Valkeinen 2023-06-19 4995 if (ret) { afe267f2d368f5 Tomi Valkeinen 2023-06-19 4996 dev_err_probe(dev, ret, "Failed to enable refclk\n"); afe267f2d368f5 Tomi Valkeinen 2023-06-19 4997 goto err_disable_vddio; afe267f2d368f5 Tomi Valkeinen 2023-06-19 4998 } afe267f2d368f5 Tomi Valkeinen 2023-06-19 4999 afe267f2d368f5 Tomi Valkeinen 2023-06-19 5000 if (priv->pd_gpio) { afe267f2d368f5 Tomi Valkeinen 2023-06-19 5001 gpiod_set_value_cansleep(priv->pd_gpio, 1); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5002 /* wait min 2 ms for reset to complete */ afe267f2d368f5 Tomi Valkeinen 2023-06-19 5003 fsleep(2000); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5004 gpiod_set_value_cansleep(priv->pd_gpio, 0); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5005 /* wait min 2 ms for power up to finish */ afe267f2d368f5 Tomi Valkeinen 2023-06-19 5006 fsleep(2000); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5007 } afe267f2d368f5 Tomi Valkeinen 2023-06-19 5008 8f512c3113756c Tomi Valkeinen 2025-03-03 5009 ret = ub960_reset(priv, true); 8f512c3113756c Tomi Valkeinen 2025-03-03 5010 if (ret) 8f512c3113756c Tomi Valkeinen 2025-03-03 5011 goto err_pd_gpio; afe267f2d368f5 Tomi Valkeinen 2023-06-19 5012 afe267f2d368f5 Tomi Valkeinen 2023-06-19 5013 /* Runtime check register accessibility */ 24868501a74402 Tomi Valkeinen 2025-03-03 5014 ret = ub960_read(priv, UB960_SR_REV_MASK, &rev_mask, NULL); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5015 if (ret) { afe267f2d368f5 Tomi Valkeinen 2023-06-19 5016 dev_err_probe(dev, ret, "Cannot read first register, abort\n"); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5017 goto err_pd_gpio; afe267f2d368f5 Tomi Valkeinen 2023-06-19 5018 } afe267f2d368f5 Tomi Valkeinen 2023-06-19 5019 afe267f2d368f5 Tomi Valkeinen 2023-06-19 5020 dev_dbg(dev, "Found %s (rev/mask %#04x)\n", priv->hw_data->model, afe267f2d368f5 Tomi Valkeinen 2023-06-19 5021 rev_mask); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5022 24868501a74402 Tomi Valkeinen 2025-03-03 5023 ret = ub960_read(priv, UB960_SR_DEVICE_STS, &dev_sts, NULL); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5024 if (ret) afe267f2d368f5 Tomi Valkeinen 2023-06-19 5025 goto err_pd_gpio; afe267f2d368f5 Tomi Valkeinen 2023-06-19 5026 ba3bdb93947c90 Tomi Valkeinen 2024-12-06 5027 if (priv->hw_data->is_ub9702) 24868501a74402 Tomi Valkeinen 2025-03-03 5028 ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq, 24868501a74402 Tomi Valkeinen 2025-03-03 5029 NULL); 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5030 else if (priv->hw_data->is_ub954) { 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5031 /* From DS90UB954-Q1 datasheet: 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5032 * "REFCLK_FREQ measurement is not synchronized. Value in this 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5033 * register should read twice and only considered valid if 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5034 * REFCLK_FREQ is unchanged between reads." 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5035 */ 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5036 unsigned long timeout = jiffies + msecs_to_jiffies(100); 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5037 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5038 do { 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5039 u8 refclk_new; 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5040 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5041 ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_new, 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5042 NULL); 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5043 if (ret) 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5044 goto err_pd_gpio; 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5045 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 @5046 if (refclk_new == refclk_freq) ^^^^^^^^^^^ This is uninitialized on the first iteration. 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5047 break; 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5048 refclk_freq = refclk_new; 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5049 } while (time_before(jiffies, timeout)); 8a8ba5651f9d39 Yemike Abhilash Chandra 2025-05-23 5050 } ba3bdb93947c90 Tomi Valkeinen 2024-12-06 5051 else 24868501a74402 Tomi Valkeinen 2025-03-03 5052 ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq, 24868501a74402 Tomi Valkeinen 2025-03-03 5053 NULL); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5054 if (ret) afe267f2d368f5 Tomi Valkeinen 2023-06-19 5055 goto err_pd_gpio; afe267f2d368f5 Tomi Valkeinen 2023-06-19 5056 afe267f2d368f5 Tomi Valkeinen 2023-06-19 5057 dev_dbg(dev, "refclk valid %u freq %u MHz (clk fw freq %lu MHz)\n", afe267f2d368f5 Tomi Valkeinen 2023-06-19 5058 !!(dev_sts & BIT(4)), refclk_freq, a56fac44beced4 Tomi Valkeinen 2024-12-06 5059 clk_get_rate(priv->refclk) / HZ_PER_MHZ); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5060 afe267f2d368f5 Tomi Valkeinen 2023-06-19 5061 /* Disable all RX ports by default */ 24868501a74402 Tomi Valkeinen 2025-03-03 5062 ret = ub960_write(priv, UB960_SR_RX_PORT_CTL, 0, NULL); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5063 if (ret) afe267f2d368f5 Tomi Valkeinen 2023-06-19 5064 goto err_pd_gpio; afe267f2d368f5 Tomi Valkeinen 2023-06-19 5065 afe267f2d368f5 Tomi Valkeinen 2023-06-19 5066 /* release GPIO lock */ afe267f2d368f5 Tomi Valkeinen 2023-06-19 5067 if (priv->hw_data->is_ub9702) { afe267f2d368f5 Tomi Valkeinen 2023-06-19 5068 ret = ub960_update_bits(priv, UB960_SR_RESET, afe267f2d368f5 Tomi Valkeinen 2023-06-19 5069 UB960_SR_RESET_GPIO_LOCK_RELEASE, 24868501a74402 Tomi Valkeinen 2025-03-03 5070 UB960_SR_RESET_GPIO_LOCK_RELEASE, 24868501a74402 Tomi Valkeinen 2025-03-03 5071 NULL); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5072 if (ret) afe267f2d368f5 Tomi Valkeinen 2023-06-19 5073 goto err_pd_gpio; afe267f2d368f5 Tomi Valkeinen 2023-06-19 5074 } afe267f2d368f5 Tomi Valkeinen 2023-06-19 5075 afe267f2d368f5 Tomi Valkeinen 2023-06-19 5076 return 0; afe267f2d368f5 Tomi Valkeinen 2023-06-19 5077 afe267f2d368f5 Tomi Valkeinen 2023-06-19 5078 err_pd_gpio: afe267f2d368f5 Tomi Valkeinen 2023-06-19 5079 gpiod_set_value_cansleep(priv->pd_gpio, 1); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5080 clk_disable_unprepare(priv->refclk); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5081 err_disable_vddio: afe267f2d368f5 Tomi Valkeinen 2023-06-19 5082 regulator_disable(priv->vddio); afe267f2d368f5 Tomi Valkeinen 2023-06-19 5083 afe267f2d368f5 Tomi Valkeinen 2023-06-19 5084 return ret; afe267f2d368f5 Tomi Valkeinen 2023-06-19 5085 } -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 0/2] Add support for DS90UB954-Q1 @ 2025-05-23 8:36 Yemike Abhilash Chandra 2025-05-23 8:36 ` [PATCH 2/2] media: i2c: ds90ub960: " Yemike Abhilash Chandra 0 siblings, 1 reply; 9+ messages in thread From: Yemike Abhilash Chandra @ 2025-05-23 8:36 UTC (permalink / raw) To: tomi.valkeinen, mchehab, robh, krzk+dt, conor+dt Cc: hverkuil, sakari.ailus, laurent.pinchart, vaishnav.a, u-kumar1, jai.luthra, linux-media, devicetree, linux-kernel, y-abhilashchandra DS90UB954-Q1 is an FPDLink-III deserializer that is mostly register compatible with DS90UB960-Q1. The main difference is that it supports half of the RX and TX ports, i.e. 2x FPDLink RX ports and 1x CSI TX port. Therefore, add support for DS90UB954 within the existing DS90UB960 bindings and the driver. Test logs: https://gist.github.com/Yemike-Abhilash-Chandra/e7af7b4f5a4e6304dd572e3a691e8b98 Note: Few differences between the DS90UB960 and DS90UB954 leveraged in this series were originally explored in an earlier submission [1], which was not merged due to the contributor being under the Russian ban list. We acknowledge the efforts made in that submission [1]. [1]: https://lore.kernel.org/all/20241015080737.16272-2-eagle.alexander923@gmail.com/ Yemike Abhilash Chandra (2): media: dt-bindings: ti,ds90ub960: Add bindings for DS90UB954-Q1 media: i2c: ds90ub960: Add support for DS90UB954-Q1 .../bindings/media/i2c/ti,ds90ub960.yaml | 1 + drivers/media/i2c/Kconfig | 2 +- drivers/media/i2c/ds90ub960.c | 46 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) -- 2.34.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 2025-05-23 8:36 [PATCH 0/2] " Yemike Abhilash Chandra @ 2025-05-23 8:36 ` Yemike Abhilash Chandra 2025-05-23 16:53 ` Jai Luthra 2025-05-27 5:40 ` Tomi Valkeinen 0 siblings, 2 replies; 9+ messages in thread From: Yemike Abhilash Chandra @ 2025-05-23 8:36 UTC (permalink / raw) To: tomi.valkeinen, mchehab, robh, krzk+dt, conor+dt Cc: hverkuil, sakari.ailus, laurent.pinchart, vaishnav.a, u-kumar1, jai.luthra, linux-media, devicetree, linux-kernel, y-abhilashchandra DS90UB954-Q1 is an FPDLink-III deserializer that is mostly register compatible with DS90UB960-Q1. The main difference is that it supports half of the RX and TX ports, i.e. 2x FPDLink RX ports and 1x CSI TX port. Some other registers are marked as reserved in the datasheet as well, notably around CSI-TX frame and line-count monitoring and some other status registers. The datasheet also does not mention anything about setting strobe position, and fails to lock the RX ports if we forcefully set it, so disable it through the hw_data. Link: https://www.ti.com/lit/gpn/ds90ub954-q1 Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com> --- drivers/media/i2c/Kconfig | 2 +- drivers/media/i2c/ds90ub960.c | 46 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index e68202954a8f..6e265e1cec20 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -1662,7 +1662,7 @@ config VIDEO_DS90UB960 select V4L2_FWNODE select VIDEO_V4L2_SUBDEV_API help - Device driver for the Texas Instruments DS90UB960 + Device driver for the Texas Instruments DS90UB954/DS90UB960 FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer. config VIDEO_MAX96714 diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index ed2cf9d247d1..38e4f006d098 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -460,6 +460,7 @@ struct ub960_hw_data { u8 num_txports; bool is_ub9702; bool is_fpdlink4; + bool is_ub954; }; enum ub960_rxport_mode { @@ -982,6 +983,10 @@ static int ub960_txport_select(struct ub960_data *priv, u8 nport) lockdep_assert_held(&priv->reg_lock); + /* TX port registers are shared for UB954*/ + if (priv->hw_data->is_ub954) + return 0; + if (priv->reg_current.txport == nport) return 0; @@ -1415,6 +1420,13 @@ static int ub960_parse_dt_txport(struct ub960_data *priv, goto err_free_vep; } + /* UB954 does not support 1.2 Gbps */ + if (priv->tx_data_rate == MHZ(1200) && priv->hw_data->is_ub954) { + dev_err(dev, "tx%u: invalid 'link-frequencies' value\n", nport); + ret = -EINVAL; + goto err_free_vep; + } + v4l2_fwnode_endpoint_free(&vep); priv->txports[nport] = txport; @@ -1572,6 +1584,10 @@ static int ub960_rxport_set_strobe_pos(struct ub960_data *priv, u8 clk_delay, data_delay; int ret = 0; + /* FIXME: After writing to this area the UB954 chip no longer responds */ + if (priv->hw_data->is_ub954) + return 0; + clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY; data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY; @@ -5021,6 +5037,27 @@ static int ub960_enable_core_hw(struct ub960_data *priv) if (priv->hw_data->is_ub9702) ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq, NULL); + else if (priv->hw_data->is_ub954) { + /* From DS90UB954-Q1 datasheet: + * "REFCLK_FREQ measurement is not synchronized. Value in this + * register should read twice and only considered valid if + * REFCLK_FREQ is unchanged between reads." + */ + unsigned long timeout = jiffies + msecs_to_jiffies(100); + + do { + u8 refclk_new; + + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_new, + NULL); + if (ret) + goto err_pd_gpio; + + if (refclk_new == refclk_freq) + break; + refclk_freq = refclk_new; + } while (time_before(jiffies, timeout)); + } else ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq, NULL); @@ -5177,6 +5214,13 @@ static void ub960_remove(struct i2c_client *client) mutex_destroy(&priv->reg_lock); } +static const struct ub960_hw_data ds90ub954_hw = { + .model = "ub954", + .num_rxports = 2, + .num_txports = 1, + .is_ub954 = true, +}; + static const struct ub960_hw_data ds90ub960_hw = { .model = "ub960", .num_rxports = 4, @@ -5192,6 +5236,7 @@ static const struct ub960_hw_data ds90ub9702_hw = { }; static const struct i2c_device_id ub960_id[] = { + { "ds90ub954-q1", (kernel_ulong_t)&ds90ub954_hw }, { "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw }, { "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw }, {} @@ -5199,6 +5244,7 @@ static const struct i2c_device_id ub960_id[] = { MODULE_DEVICE_TABLE(i2c, ub960_id); static const struct of_device_id ub960_dt_ids[] = { + { .compatible = "ti,ds90ub954-q1", .data = &ds90ub954_hw }, { .compatible = "ti,ds90ub960-q1", .data = &ds90ub960_hw }, { .compatible = "ti,ds90ub9702-q1", .data = &ds90ub9702_hw }, {} -- 2.34.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 2025-05-23 8:36 ` [PATCH 2/2] media: i2c: ds90ub960: " Yemike Abhilash Chandra @ 2025-05-23 16:53 ` Jai Luthra 2025-05-26 6:24 ` Yemike Abhilash Chandra 2025-05-27 5:40 ` Tomi Valkeinen 1 sibling, 1 reply; 9+ messages in thread From: Jai Luthra @ 2025-05-23 16:53 UTC (permalink / raw) To: Yemike Abhilash Chandra, conor+dt, krzk+dt, mchehab, robh, tomi.valkeinen Cc: hverkuil, sakari.ailus, laurent.pinchart, vaishnav.a, u-kumar1, jai.luthra, linux-media, devicetree, linux-kernel, y-abhilashchandra Hi Abhilash, Thanks for the patch. Quoting Yemike Abhilash Chandra (2025-05-23 14:06:55) > DS90UB954-Q1 is an FPDLink-III deserializer that is mostly register > compatible with DS90UB960-Q1. The main difference is that it supports > half of the RX and TX ports, i.e. 2x FPDLink RX ports and 1x CSI TX > port. > > Some other registers are marked as reserved in the datasheet as well, > notably around CSI-TX frame and line-count monitoring and some other > status registers. The datasheet also does not mention anything about So what happens when userspace calls LOG_STATUS and the driver tries to read these monitoring registers? Are these populated in the device but just marked as reserved in the datasheet? Whatever is the case, please make sure the driver doesn't crash, and update the commit message with the reality if the datasheet is wrong. > setting strobe position, and fails to lock the RX ports if we forcefully > set it, so disable it through the hw_data. > > Link: https://www.ti.com/lit/gpn/ds90ub954-q1 > Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com> > --- > drivers/media/i2c/Kconfig | 2 +- > drivers/media/i2c/ds90ub960.c | 46 +++++++++++++++++++++++++++++++++++ > 2 files changed, 47 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig > index e68202954a8f..6e265e1cec20 100644 > --- a/drivers/media/i2c/Kconfig > +++ b/drivers/media/i2c/Kconfig > @@ -1662,7 +1662,7 @@ config VIDEO_DS90UB960 > select V4L2_FWNODE > select VIDEO_V4L2_SUBDEV_API > help > - Device driver for the Texas Instruments DS90UB960 > + Device driver for the Texas Instruments DS90UB954/DS90UB960 > FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer. nit: Device driver for the Texas Instruments DS90UB954, DS90UB960 FPD-Link III Deserializers and DS90UB9702 FPD-Link IV Deserializer. > > config VIDEO_MAX96714 > diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c > index ed2cf9d247d1..38e4f006d098 100644 > --- a/drivers/media/i2c/ds90ub960.c > +++ b/drivers/media/i2c/ds90ub960.c > @@ -460,6 +460,7 @@ struct ub960_hw_data { > u8 num_txports; > bool is_ub9702; > bool is_fpdlink4; > + bool is_ub954; > }; > > enum ub960_rxport_mode { > @@ -982,6 +983,10 @@ static int ub960_txport_select(struct ub960_data *priv, u8 nport) > > lockdep_assert_held(&priv->reg_lock); > > + /* TX port registers are shared for UB954*/ > + if (priv->hw_data->is_ub954) > + return 0; > + nit: This could be moved above the assertion > if (priv->reg_current.txport == nport) > return 0; > > @@ -1415,6 +1420,13 @@ static int ub960_parse_dt_txport(struct ub960_data *priv, > goto err_free_vep; > } > > + /* UB954 does not support 1.2 Gbps */ > + if (priv->tx_data_rate == MHZ(1200) && priv->hw_data->is_ub954) { > + dev_err(dev, "tx%u: invalid 'link-frequencies' value\n", nport); > + ret = -EINVAL; > + goto err_free_vep; > + } > + The error handling is exactly the same as the previous if {} block that checks the allowed data rates for UB960. IMO cleaner to move this condition in that block. Maybe even a separate table for allowed data-rates for each chip, but that is probably overkill. > v4l2_fwnode_endpoint_free(&vep); > > priv->txports[nport] = txport; > @@ -1572,6 +1584,10 @@ static int ub960_rxport_set_strobe_pos(struct ub960_data *priv, > u8 clk_delay, data_delay; > int ret = 0; > > + /* FIXME: After writing to this area the UB954 chip no longer responds */ > + if (priv->hw_data->is_ub954) > + return 0; > + It would be good to understand if this is a hardware limitation or not. Tomi, do you have any idea? > clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY; > data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY; > > @@ -5021,6 +5037,27 @@ static int ub960_enable_core_hw(struct ub960_data *priv) > if (priv->hw_data->is_ub9702) > ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq, > NULL); > + else if (priv->hw_data->is_ub954) { > + /* From DS90UB954-Q1 datasheet: > + * "REFCLK_FREQ measurement is not synchronized. Value in this > + * register should read twice and only considered valid if * register should be read twice and only considered valid if > + * REFCLK_FREQ is unchanged between reads." > + */ > + unsigned long timeout = jiffies + msecs_to_jiffies(100); > + > + do { > + u8 refclk_new; > + > + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_new, > + NULL); > + if (ret) > + goto err_pd_gpio; > + > + if (refclk_new == refclk_freq) > + break; > + refclk_freq = refclk_new; > + } while (time_before(jiffies, timeout)); > + } Hmm.. in your testing did you find this actually requiring more than one read? I'm surprised because this is missing from UB960 which is an older device. > else > ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq, > NULL); > @@ -5177,6 +5214,13 @@ static void ub960_remove(struct i2c_client *client) > mutex_destroy(&priv->reg_lock); > } > > +static const struct ub960_hw_data ds90ub954_hw = { > + .model = "ub954", > + .num_rxports = 2, > + .num_txports = 1, > + .is_ub954 = true, > +}; > + > static const struct ub960_hw_data ds90ub960_hw = { > .model = "ub960", > .num_rxports = 4, > @@ -5192,6 +5236,7 @@ static const struct ub960_hw_data ds90ub9702_hw = { > }; > > static const struct i2c_device_id ub960_id[] = { > + { "ds90ub954-q1", (kernel_ulong_t)&ds90ub954_hw }, > { "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw }, > { "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw }, > {} > @@ -5199,6 +5244,7 @@ static const struct i2c_device_id ub960_id[] = { > MODULE_DEVICE_TABLE(i2c, ub960_id); > > static const struct of_device_id ub960_dt_ids[] = { > + { .compatible = "ti,ds90ub954-q1", .data = &ds90ub954_hw }, > { .compatible = "ti,ds90ub960-q1", .data = &ds90ub960_hw }, > { .compatible = "ti,ds90ub9702-q1", .data = &ds90ub9702_hw }, > {} > -- > 2.34.1 > > Thanks, Jai ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 2025-05-23 16:53 ` Jai Luthra @ 2025-05-26 6:24 ` Yemike Abhilash Chandra 0 siblings, 0 replies; 9+ messages in thread From: Yemike Abhilash Chandra @ 2025-05-26 6:24 UTC (permalink / raw) To: Jai Luthra, conor+dt, krzk+dt, mchehab, robh, tomi.valkeinen Cc: hverkuil, sakari.ailus, laurent.pinchart, vaishnav.a, u-kumar1, jai.luthra, linux-media, devicetree, linux-kernel Hi Jai, Thanks for the review. On 23/05/25 22:23, Jai Luthra wrote: > Hi Abhilash, > > Thanks for the patch. > > Quoting Yemike Abhilash Chandra (2025-05-23 14:06:55) >> DS90UB954-Q1 is an FPDLink-III deserializer that is mostly register >> compatible with DS90UB960-Q1. The main difference is that it supports >> half of the RX and TX ports, i.e. 2x FPDLink RX ports and 1x CSI TX >> port. >> >> Some other registers are marked as reserved in the datasheet as well, >> notably around CSI-TX frame and line-count monitoring and some other >> status registers. The datasheet also does not mention anything about > > So what happens when userspace calls LOG_STATUS and the driver tries to > read these monitoring registers? Are these populated in the device but just > marked as reserved in the datasheet? > > Whatever is the case, please make sure the driver doesn't crash, and update > the commit message with the reality if the datasheet is wrong. > I don't see a crash while doing a log-status [1]. In the driver, we check what TX and RX ports are active from the HW data and the do a register read accordingly. That should be fine I believe. >> setting strobe position, and fails to lock the RX ports if we forcefully >> set it, so disable it through the hw_data. >> >> Link: https://www.ti.com/lit/gpn/ds90ub954-q1 >> Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com> >> --- >> drivers/media/i2c/Kconfig | 2 +- >> drivers/media/i2c/ds90ub960.c | 46 +++++++++++++++++++++++++++++++++++ >> 2 files changed, 47 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig >> index e68202954a8f..6e265e1cec20 100644 >> --- a/drivers/media/i2c/Kconfig >> +++ b/drivers/media/i2c/Kconfig >> @@ -1662,7 +1662,7 @@ config VIDEO_DS90UB960 >> select V4L2_FWNODE >> select VIDEO_V4L2_SUBDEV_API >> help >> - Device driver for the Texas Instruments DS90UB960 >> + Device driver for the Texas Instruments DS90UB954/DS90UB960 >> FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer. > > nit: > Device driver for the Texas Instruments DS90UB954, DS90UB960 > FPD-Link III Deserializers and DS90UB9702 FPD-Link IV Deserializer. > >> >> config VIDEO_MAX96714 >> diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c >> index ed2cf9d247d1..38e4f006d098 100644 >> --- a/drivers/media/i2c/ds90ub960.c >> +++ b/drivers/media/i2c/ds90ub960.c >> @@ -460,6 +460,7 @@ struct ub960_hw_data { >> u8 num_txports; >> bool is_ub9702; >> bool is_fpdlink4; >> + bool is_ub954; >> }; >> >> enum ub960_rxport_mode { >> @@ -982,6 +983,10 @@ static int ub960_txport_select(struct ub960_data *priv, u8 nport) >> >> lockdep_assert_held(&priv->reg_lock); >> >> + /* TX port registers are shared for UB954*/ >> + if (priv->hw_data->is_ub954) >> + return 0; >> + > > nit: This could be moved above the assertion Will do that in next revision. > >> if (priv->reg_current.txport == nport) >> return 0; >> >> @@ -1415,6 +1420,13 @@ static int ub960_parse_dt_txport(struct ub960_data *priv, >> goto err_free_vep; >> } >> >> + /* UB954 does not support 1.2 Gbps */ >> + if (priv->tx_data_rate == MHZ(1200) && priv->hw_data->is_ub954) { >> + dev_err(dev, "tx%u: invalid 'link-frequencies' value\n", nport); >> + ret = -EINVAL; >> + goto err_free_vep; >> + } >> + > > The error handling is exactly the same as the previous if {} block that > checks the allowed data rates for UB960. IMO cleaner to move this condition > in that block. > Noted, will try to do that in a cleaner way in next revision. > Maybe even a separate table for allowed data-rates for each chip, but that > is probably overkill. > >> v4l2_fwnode_endpoint_free(&vep); >> >> priv->txports[nport] = txport; >> @@ -1572,6 +1584,10 @@ static int ub960_rxport_set_strobe_pos(struct ub960_data *priv, >> u8 clk_delay, data_delay; >> int ret = 0; >> >> + /* FIXME: After writing to this area the UB954 chip no longer responds */ >> + if (priv->hw_data->is_ub954) >> + return 0; >> + > > It would be good to understand if this is a hardware limitation or not. > Tomi, do you have any idea? > >> clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY; >> data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY; >> >> @@ -5021,6 +5037,27 @@ static int ub960_enable_core_hw(struct ub960_data *priv) >> if (priv->hw_data->is_ub9702) >> ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq, >> NULL); >> + else if (priv->hw_data->is_ub954) { >> + /* From DS90UB954-Q1 datasheet: >> + * "REFCLK_FREQ measurement is not synchronized. Value in this >> + * register should read twice and only considered valid if > > * register should be read twice and only considered valid if > >> + * REFCLK_FREQ is unchanged between reads." >> + */ >> + unsigned long timeout = jiffies + msecs_to_jiffies(100); >> + >> + do { >> + u8 refclk_new; >> + >> + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_new, >> + NULL); >> + if (ret) >> + goto err_pd_gpio; >> + >> + if (refclk_new == refclk_freq) >> + break; >> + refclk_freq = refclk_new; >> + } while (time_before(jiffies, timeout)); >> + } > > Hmm.. in your testing did you find this actually requiring more than one > read? > > I'm surprised because this is missing from UB960 which is an older device. > In my testing (around 20 reboots) , I had to do only 1 check i.e just 2 iterations. I am not sure on how to proceed but the data sheet at7.6.121 REFCLK_FREQ Register clearly specifies the below. "REFCLK_FREQ measurement is not synchronized. Value in this register should read twice and only considered valid if REFCLK_FREQ is unchanged between reads." Thanks and Regards, Abhilash Chandra [1]: https://gist.github.com/Yemike-Abhilash-Chandra/dc07a6389d06648d9e80de23d8cae954 >> else >> ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq, >> NULL); >> @@ -5177,6 +5214,13 @@ static void ub960_remove(struct i2c_client *client) >> mutex_destroy(&priv->reg_lock); >> } >> >> +static const struct ub960_hw_data ds90ub954_hw = { >> + .model = "ub954", >> + .num_rxports = 2, >> + .num_txports = 1, >> + .is_ub954 = true, >> +}; >> + >> static const struct ub960_hw_data ds90ub960_hw = { >> .model = "ub960", >> .num_rxports = 4, >> @@ -5192,6 +5236,7 @@ static const struct ub960_hw_data ds90ub9702_hw = { >> }; >> >> static const struct i2c_device_id ub960_id[] = { >> + { "ds90ub954-q1", (kernel_ulong_t)&ds90ub954_hw }, >> { "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw }, >> { "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw }, >> {} >> @@ -5199,6 +5244,7 @@ static const struct i2c_device_id ub960_id[] = { >> MODULE_DEVICE_TABLE(i2c, ub960_id); >> >> static const struct of_device_id ub960_dt_ids[] = { >> + { .compatible = "ti,ds90ub954-q1", .data = &ds90ub954_hw }, >> { .compatible = "ti,ds90ub960-q1", .data = &ds90ub960_hw }, >> { .compatible = "ti,ds90ub9702-q1", .data = &ds90ub9702_hw }, >> {} >> -- >> 2.34.1 >> >> > > Thanks, > Jai ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 2025-05-23 8:36 ` [PATCH 2/2] media: i2c: ds90ub960: " Yemike Abhilash Chandra 2025-05-23 16:53 ` Jai Luthra @ 2025-05-27 5:40 ` Tomi Valkeinen 2025-05-28 6:25 ` Yemike Abhilash Chandra 1 sibling, 1 reply; 9+ messages in thread From: Tomi Valkeinen @ 2025-05-27 5:40 UTC (permalink / raw) To: Yemike Abhilash Chandra Cc: hverkuil, sakari.ailus, laurent.pinchart, vaishnav.a, u-kumar1, jai.luthra, linux-media, devicetree, linux-kernel, mchehab, robh, krzk+dt, conor+dt Hi, On 23/05/2025 11:36, Yemike Abhilash Chandra wrote: > DS90UB954-Q1 is an FPDLink-III deserializer that is mostly register > compatible with DS90UB960-Q1. The main difference is that it supports > half of the RX and TX ports, i.e. 2x FPDLink RX ports and 1x CSI TX > port. > > Some other registers are marked as reserved in the datasheet as well, > notably around CSI-TX frame and line-count monitoring and some other Hmm what does that mean? That in log_status we show random data (or maybe always 0) for these? > status registers. The datasheet also does not mention anything about > setting strobe position, and fails to lock the RX ports if we forcefully > set it, so disable it through the hw_data. This app-note has some details: https://www.ti.com/lit/an/snla301/snla301.pdf > Link: https://www.ti.com/lit/gpn/ds90ub954-q1 > Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com> > --- > drivers/media/i2c/Kconfig | 2 +- > drivers/media/i2c/ds90ub960.c | 46 +++++++++++++++++++++++++++++++++++ > 2 files changed, 47 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig > index e68202954a8f..6e265e1cec20 100644 > --- a/drivers/media/i2c/Kconfig > +++ b/drivers/media/i2c/Kconfig > @@ -1662,7 +1662,7 @@ config VIDEO_DS90UB960 > select V4L2_FWNODE > select VIDEO_V4L2_SUBDEV_API > help > - Device driver for the Texas Instruments DS90UB960 > + Device driver for the Texas Instruments DS90UB954/DS90UB960 > FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer. > > config VIDEO_MAX96714 > diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c > index ed2cf9d247d1..38e4f006d098 100644 > --- a/drivers/media/i2c/ds90ub960.c > +++ b/drivers/media/i2c/ds90ub960.c > @@ -460,6 +460,7 @@ struct ub960_hw_data { > u8 num_txports; > bool is_ub9702; > bool is_fpdlink4; > + bool is_ub954; No, let's not add any more of these. We should have enums for the device model and the "family" (ub954/ub960 are clearly of the same family, whereas ub9702 is of a newer one). > }; > > enum ub960_rxport_mode { > @@ -982,6 +983,10 @@ static int ub960_txport_select(struct ub960_data *priv, u8 nport) > > lockdep_assert_held(&priv->reg_lock); > > + /* TX port registers are shared for UB954*/ Space missing at the end. What does the comment mean? "registers are shared"? I think it's good to have this after the lockdep assert. The lock rules are in place, even if on ub954 we don't do anything here. > + if (priv->hw_data->is_ub954) > + return 0; > + > if (priv->reg_current.txport == nport) > return 0; > > @@ -1415,6 +1420,13 @@ static int ub960_parse_dt_txport(struct ub960_data *priv, > goto err_free_vep; > } > > + /* UB954 does not support 1.2 Gbps */ > + if (priv->tx_data_rate == MHZ(1200) && priv->hw_data->is_ub954) { Test for ub954 first, 1200 MHz second. It's more logical for the reader that way. > + dev_err(dev, "tx%u: invalid 'link-frequencies' value\n", nport); > + ret = -EINVAL; > + goto err_free_vep; > + } > + > v4l2_fwnode_endpoint_free(&vep); > > priv->txports[nport] = txport; > @@ -1572,6 +1584,10 @@ static int ub960_rxport_set_strobe_pos(struct ub960_data *priv, > u8 clk_delay, data_delay; > int ret = 0; > > + /* FIXME: After writing to this area the UB954 chip no longer responds */ > + if (priv->hw_data->is_ub954) > + return 0; > + Check the app note. It would be nice to have this working, as, afaik, the HW functionality should be the same on ub954 and ub960. > clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY; > data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY; > > @@ -5021,6 +5037,27 @@ static int ub960_enable_core_hw(struct ub960_data *priv) > if (priv->hw_data->is_ub9702) > ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq, > NULL); > + else if (priv->hw_data->is_ub954) { > + /* From DS90UB954-Q1 datasheet: > + * "REFCLK_FREQ measurement is not synchronized. Value in this > + * register should read twice and only considered valid if > + * REFCLK_FREQ is unchanged between reads." > + */ > + unsigned long timeout = jiffies + msecs_to_jiffies(100); > + > + do { > + u8 refclk_new; > + > + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_new, > + NULL); > + if (ret) > + goto err_pd_gpio; > + > + if (refclk_new == refclk_freq) > + break; > + refclk_freq = refclk_new; > + } while (time_before(jiffies, timeout)); > + } This feels a bit too much for a not-that-important debug print... As the tests show that a single read is (practically always?) enough, I think we can just use the same code as for ub960. Maybe add a comment about it, though. Tomi > else > ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq, > NULL); > @@ -5177,6 +5214,13 @@ static void ub960_remove(struct i2c_client *client) > mutex_destroy(&priv->reg_lock); > } > > +static const struct ub960_hw_data ds90ub954_hw = { > + .model = "ub954", > + .num_rxports = 2, > + .num_txports = 1, > + .is_ub954 = true, > +}; > + > static const struct ub960_hw_data ds90ub960_hw = { > .model = "ub960", > .num_rxports = 4, > @@ -5192,6 +5236,7 @@ static const struct ub960_hw_data ds90ub9702_hw = { > }; > > static const struct i2c_device_id ub960_id[] = { > + { "ds90ub954-q1", (kernel_ulong_t)&ds90ub954_hw }, > { "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw }, > { "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw }, > {} > @@ -5199,6 +5244,7 @@ static const struct i2c_device_id ub960_id[] = { > MODULE_DEVICE_TABLE(i2c, ub960_id); > > static const struct of_device_id ub960_dt_ids[] = { > + { .compatible = "ti,ds90ub954-q1", .data = &ds90ub954_hw }, > { .compatible = "ti,ds90ub960-q1", .data = &ds90ub960_hw }, > { .compatible = "ti,ds90ub9702-q1", .data = &ds90ub9702_hw }, > {} ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 2025-05-27 5:40 ` Tomi Valkeinen @ 2025-05-28 6:25 ` Yemike Abhilash Chandra 2025-06-02 7:16 ` Tomi Valkeinen 0 siblings, 1 reply; 9+ messages in thread From: Yemike Abhilash Chandra @ 2025-05-28 6:25 UTC (permalink / raw) To: Tomi Valkeinen Cc: hverkuil, sakari.ailus, laurent.pinchart, vaishnav.a, u-kumar1, jai.luthra, linux-media, devicetree, linux-kernel, mchehab, robh, krzk+dt, conor+dt Hi Tomi, Thanks for the review. On 27/05/25 11:10, Tomi Valkeinen wrote: > Hi, > > On 23/05/2025 11:36, Yemike Abhilash Chandra wrote: >> DS90UB954-Q1 is an FPDLink-III deserializer that is mostly register >> compatible with DS90UB960-Q1. The main difference is that it supports >> half of the RX and TX ports, i.e. 2x FPDLink RX ports and 1x CSI TX >> port. >> >> Some other registers are marked as reserved in the datasheet as well, >> notably around CSI-TX frame and line-count monitoring and some other > > Hmm what does that mean? That in log_status we show random data (or > maybe always 0) for these? > It seems like it is showing 0's for these. I streamed around 100 frames. But the frame counter and line counter returned is 0. Please find the logs at [1]. >> status registers. The datasheet also does not mention anything about >> setting strobe position, and fails to lock the RX ports if we forcefully >> set it, so disable it through the hw_data. > > This app-note has some details: > > https://www.ti.com/lit/an/snla301/snla301.pdf > >> Link: https://www.ti.com/lit/gpn/ds90ub954-q1 >> Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com> >> --- >> drivers/media/i2c/Kconfig | 2 +- >> drivers/media/i2c/ds90ub960.c | 46 +++++++++++++++++++++++++++++++++++ >> 2 files changed, 47 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig >> index e68202954a8f..6e265e1cec20 100644 >> --- a/drivers/media/i2c/Kconfig >> +++ b/drivers/media/i2c/Kconfig >> @@ -1662,7 +1662,7 @@ config VIDEO_DS90UB960 >> select V4L2_FWNODE >> select VIDEO_V4L2_SUBDEV_API >> help >> - Device driver for the Texas Instruments DS90UB960 >> + Device driver for the Texas Instruments DS90UB954/DS90UB960 >> FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer. >> >> config VIDEO_MAX96714 >> diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c >> index ed2cf9d247d1..38e4f006d098 100644 >> --- a/drivers/media/i2c/ds90ub960.c >> +++ b/drivers/media/i2c/ds90ub960.c >> @@ -460,6 +460,7 @@ struct ub960_hw_data { >> u8 num_txports; >> bool is_ub9702; >> bool is_fpdlink4; >> + bool is_ub954; > > No, let's not add any more of these. We should have enums for the device > model and the "family" (ub954/ub960 are clearly of the same family, > whereas ub9702 is of a newer one). > Got it. I will add enums in the next revision. >> }; >> >> enum ub960_rxport_mode { >> @@ -982,6 +983,10 @@ static int ub960_txport_select(struct ub960_data *priv, u8 nport) >> >> lockdep_assert_held(&priv->reg_lock); >> >> + /* TX port registers are shared for UB954*/ > > Space missing at the end. What does the comment mean? "registers are > shared"? > Apologies for the inaccurate comment description, My intention to comment that the tx_port_select function does not make sense for UB954, since we have only 1 CSI TX. May be I can have something like below. /** UB954 has only 1 CSI TX. Hence, no need to select **/ > I think it's good to have this after the lockdep assert. The lock rules > are in place, even if on ub954 we don't do anything here. > >> + if (priv->hw_data->is_ub954) >> + return 0; >> + >> if (priv->reg_current.txport == nport) >> return 0; >> >> @@ -1415,6 +1420,13 @@ static int ub960_parse_dt_txport(struct ub960_data *priv, >> goto err_free_vep; >> } >> >> + /* UB954 does not support 1.2 Gbps */ >> + if (priv->tx_data_rate == MHZ(1200) && priv->hw_data->is_ub954) { > > Test for ub954 first, 1200 MHz second. It's more logical for the reader > that way. > Noted, will do that in the next revision. >> + dev_err(dev, "tx%u: invalid 'link-frequencies' value\n", nport); >> + ret = -EINVAL; >> + goto err_free_vep; >> + } >> + >> v4l2_fwnode_endpoint_free(&vep); >> >> priv->txports[nport] = txport; >> @@ -1572,6 +1584,10 @@ static int ub960_rxport_set_strobe_pos(struct ub960_data *priv, >> u8 clk_delay, data_delay; >> int ret = 0; >> >> + /* FIXME: After writing to this area the UB954 chip no longer responds */ >> + if (priv->hw_data->is_ub954) >> + return 0; >> + > > Check the app note. It would be nice to have this working, as, afaik, > the HW functionality should be the same on ub954 and ub960. > I tried referring the app note and changed the strobe position values accordingly, but it did not help. Since the app note also specifies the below at Table 2 Strobe Adaption Modes " AEQ Adaption Mode--> Strobe position is selected as part of AEQ. This is the default mode. Manual Adaption Mode --> The strobe position is selected manually and will remain at the specified position until a new one is chosen. This mode is recommended as an evaluation and debugging mode " Since, under the default settings, the strobe position is selected as part of the AEQ process. Can we limit the ub960_rxport_set_strobe_pos function to only UB960 and UB9702. >> clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY; >> data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY; >> >> @@ -5021,6 +5037,27 @@ static int ub960_enable_core_hw(struct ub960_data *priv) >> if (priv->hw_data->is_ub9702) >> ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq, >> NULL); >> + else if (priv->hw_data->is_ub954) { >> + /* From DS90UB954-Q1 datasheet: >> + * "REFCLK_FREQ measurement is not synchronized. Value in this >> + * register should read twice and only considered valid if >> + * REFCLK_FREQ is unchanged between reads." >> + */ >> + unsigned long timeout = jiffies + msecs_to_jiffies(100); >> + >> + do { >> + u8 refclk_new; >> + >> + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_new, >> + NULL); >> + if (ret) >> + goto err_pd_gpio; >> + >> + if (refclk_new == refclk_freq) >> + break; >> + refclk_freq = refclk_new; >> + } while (time_before(jiffies, timeout)); >> + } > > This feels a bit too much for a not-that-important debug print... As the > tests show that a single read is (practically always?) enough, I think > we can just use the same code as for ub960. Maybe add a comment about > it, though. > okay, I will use the same code that is being used for UB960 and will add a comment about that. Thanks and Regards, Abhilash Chandra [1]: https://gist.github.com/Yemike-Abhilash-Chandra/c6b3da2a10586567a3a4179a2b20d21b > Tomi > >> else >> ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq, >> NULL); >> @@ -5177,6 +5214,13 @@ static void ub960_remove(struct i2c_client *client) >> mutex_destroy(&priv->reg_lock); >> } >> >> +static const struct ub960_hw_data ds90ub954_hw = { >> + .model = "ub954", >> + .num_rxports = 2, >> + .num_txports = 1, >> + .is_ub954 = true, >> +}; >> + >> static const struct ub960_hw_data ds90ub960_hw = { >> .model = "ub960", >> .num_rxports = 4, >> @@ -5192,6 +5236,7 @@ static const struct ub960_hw_data ds90ub9702_hw = { >> }; >> >> static const struct i2c_device_id ub960_id[] = { >> + { "ds90ub954-q1", (kernel_ulong_t)&ds90ub954_hw }, >> { "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw }, >> { "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw }, >> {} >> @@ -5199,6 +5244,7 @@ static const struct i2c_device_id ub960_id[] = { >> MODULE_DEVICE_TABLE(i2c, ub960_id); >> >> static const struct of_device_id ub960_dt_ids[] = { >> + { .compatible = "ti,ds90ub954-q1", .data = &ds90ub954_hw }, >> { .compatible = "ti,ds90ub960-q1", .data = &ds90ub960_hw }, >> { .compatible = "ti,ds90ub9702-q1", .data = &ds90ub9702_hw }, >> {} > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 2025-05-28 6:25 ` Yemike Abhilash Chandra @ 2025-06-02 7:16 ` Tomi Valkeinen 2025-06-02 10:54 ` Yemike Abhilash Chandra 0 siblings, 1 reply; 9+ messages in thread From: Tomi Valkeinen @ 2025-06-02 7:16 UTC (permalink / raw) To: Yemike Abhilash Chandra Cc: hverkuil, sakari.ailus, laurent.pinchart, vaishnav.a, u-kumar1, jai.luthra, linux-media, devicetree, linux-kernel, mchehab, robh, krzk+dt, conor+dt Hi, On 28/05/2025 09:25, Yemike Abhilash Chandra wrote: > Hi Tomi, > > Thanks for the review. > > On 27/05/25 11:10, Tomi Valkeinen wrote: >> Hi, >> >> On 23/05/2025 11:36, Yemike Abhilash Chandra wrote: >>> DS90UB954-Q1 is an FPDLink-III deserializer that is mostly register >>> compatible with DS90UB960-Q1. The main difference is that it supports >>> half of the RX and TX ports, i.e. 2x FPDLink RX ports and 1x CSI TX >>> port. >>> >>> Some other registers are marked as reserved in the datasheet as well, >>> notably around CSI-TX frame and line-count monitoring and some other >> >> Hmm what does that mean? That in log_status we show random data (or >> maybe always 0) for these? >> > > It seems like it is showing 0's for these. I streamed around 100 frames. > But the frame counter and line counter returned is 0. Please find the > logs at [1]. If the registers are marked as reserved and don't function, we should not use them. Here it doesn't do any harm when running the code, but it does decrease the usefulness of log_status if the user is shown data that is wrong (and the user most likely doesn't know it's wrong). >>> status registers. The datasheet also does not mention anything about >>> setting strobe position, and fails to lock the RX ports if we forcefully >>> set it, so disable it through the hw_data. >> >> This app-note has some details: >> >> https://www.ti.com/lit/an/snla301/snla301.pdf >> >>> Link: https://www.ti.com/lit/gpn/ds90ub954-q1 >>> Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com> >>> --- >>> drivers/media/i2c/Kconfig | 2 +- >>> drivers/media/i2c/ds90ub960.c | 46 +++++++++++++++++++++++++++++++++++ >>> 2 files changed, 47 insertions(+), 1 deletion(-) >>> >>> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig >>> index e68202954a8f..6e265e1cec20 100644 >>> --- a/drivers/media/i2c/Kconfig >>> +++ b/drivers/media/i2c/Kconfig >>> @@ -1662,7 +1662,7 @@ config VIDEO_DS90UB960 >>> select V4L2_FWNODE >>> select VIDEO_V4L2_SUBDEV_API >>> help >>> - Device driver for the Texas Instruments DS90UB960 >>> + Device driver for the Texas Instruments DS90UB954/DS90UB960 >>> FPD-Link III Deserializer and DS90UB9702 FPD-Link IV >>> Deserializer. >>> config VIDEO_MAX96714 >>> diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ >>> ds90ub960.c >>> index ed2cf9d247d1..38e4f006d098 100644 >>> --- a/drivers/media/i2c/ds90ub960.c >>> +++ b/drivers/media/i2c/ds90ub960.c >>> @@ -460,6 +460,7 @@ struct ub960_hw_data { >>> u8 num_txports; >>> bool is_ub9702; >>> bool is_fpdlink4; >>> + bool is_ub954; >> >> No, let's not add any more of these. We should have enums for the device >> model and the "family" (ub954/ub960 are clearly of the same family, >> whereas ub9702 is of a newer one). >> > > Got it. I will add enums in the next revision. > >>> }; >>> enum ub960_rxport_mode { >>> @@ -982,6 +983,10 @@ static int ub960_txport_select(struct ub960_data >>> *priv, u8 nport) >>> lockdep_assert_held(&priv->reg_lock); >>> + /* TX port registers are shared for UB954*/ >> >> Space missing at the end. What does the comment mean? "registers are >> shared"? >> > > Apologies for the inaccurate comment description, My intention to > comment that the tx_port_select function does not make sense for > UB954, since we have only 1 CSI TX. May be I can have something > like below. > > /** UB954 has only 1 CSI TX. Hence, no need to select **/ > >> I think it's good to have this after the lockdep assert. The lock rules >> are in place, even if on ub954 we don't do anything here. >> >>> + if (priv->hw_data->is_ub954) >>> + return 0; >>> + >>> if (priv->reg_current.txport == nport) >>> return 0; >>> @@ -1415,6 +1420,13 @@ static int ub960_parse_dt_txport(struct >>> ub960_data *priv, >>> goto err_free_vep; >>> } >>> + /* UB954 does not support 1.2 Gbps */ >>> + if (priv->tx_data_rate == MHZ(1200) && priv->hw_data->is_ub954) { >> >> Test for ub954 first, 1200 MHz second. It's more logical for the reader >> that way. >> > > Noted, will do that in the next revision. > >>> + dev_err(dev, "tx%u: invalid 'link-frequencies' value\n", >>> nport); >>> + ret = -EINVAL; >>> + goto err_free_vep; >>> + } >>> + >>> v4l2_fwnode_endpoint_free(&vep); >>> priv->txports[nport] = txport; >>> @@ -1572,6 +1584,10 @@ static int ub960_rxport_set_strobe_pos(struct >>> ub960_data *priv, >>> u8 clk_delay, data_delay; >>> int ret = 0; >>> + /* FIXME: After writing to this area the UB954 chip no longer >>> responds */ >>> + if (priv->hw_data->is_ub954) >>> + return 0; >>> + >> >> Check the app note. It would be nice to have this working, as, afaik, >> the HW functionality should be the same on ub954 and ub960. >> > > I tried referring the app note and changed the strobe position values > accordingly, but it did not help. > > Since the app note also specifies the below at Table 2 Strobe Adaption > Modes > > " > AEQ Adaption Mode--> Strobe position is selected as part of AEQ. This is > the default mode. > > Manual Adaption Mode --> The strobe position is selected manually and > will remain at > the specified position until a new one is chosen. This mode is > recommended as an > evaluation and debugging mode " > > Since, under the default settings, the strobe position is selected as > part of the AEQ process. > Can we limit the ub960_rxport_set_strobe_pos function to only UB960 and > UB9702. Ok. But it doesn't sound good if we just skip the ub960_rxport_set_strobe_pos(), but keep all the other EQ related writes. I.e. we do the EQ config partially, and leave out parts that, for unknown reasons, seem to cause problems... So probably the check should be in ub960_rxport_config_eq(). With a FIXME comment, and a short note where it fails. That said, if everyone (?) agrees that the HW should support this, it would be really nice if you can keep poking the FPD-Link people in TI and try to get clarification on what's going on (what's the diff between ub960 and ub954). Btw, did you look at the other EQ related writes, and check if they're valid for ub954? Tomi >>> clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY; >>> data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY; >>> @@ -5021,6 +5037,27 @@ static int ub960_enable_core_hw(struct >>> ub960_data *priv) >>> if (priv->hw_data->is_ub9702) >>> ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq, >>> NULL); >>> + else if (priv->hw_data->is_ub954) { >>> + /* From DS90UB954-Q1 datasheet: >>> + * "REFCLK_FREQ measurement is not synchronized. Value in this >>> + * register should read twice and only considered valid if >>> + * REFCLK_FREQ is unchanged between reads." >>> + */ >>> + unsigned long timeout = jiffies + msecs_to_jiffies(100); >>> + >>> + do { >>> + u8 refclk_new; >>> + >>> + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_new, >>> + NULL); >>> + if (ret) >>> + goto err_pd_gpio; >>> + >>> + if (refclk_new == refclk_freq) >>> + break; >>> + refclk_freq = refclk_new; >>> + } while (time_before(jiffies, timeout)); >>> + } >> >> This feels a bit too much for a not-that-important debug print... As the >> tests show that a single read is (practically always?) enough, I think >> we can just use the same code as for ub960. Maybe add a comment about >> it, though. >> > > okay, I will use the same code that is being used for UB960 and will add > a comment > about that. > > Thanks and Regards, > Abhilash Chandra > > [1]: https://gist.github.com/Yemike-Abhilash-Chandra/ > c6b3da2a10586567a3a4179a2b20d21b > >> Tomi >> >>> else >>> ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq, >>> NULL); >>> @@ -5177,6 +5214,13 @@ static void ub960_remove(struct i2c_client >>> *client) >>> mutex_destroy(&priv->reg_lock); >>> } >>> +static const struct ub960_hw_data ds90ub954_hw = { >>> + .model = "ub954", >>> + .num_rxports = 2, >>> + .num_txports = 1, >>> + .is_ub954 = true, >>> +}; >>> + >>> static const struct ub960_hw_data ds90ub960_hw = { >>> .model = "ub960", >>> .num_rxports = 4, >>> @@ -5192,6 +5236,7 @@ static const struct ub960_hw_data ds90ub9702_hw >>> = { >>> }; >>> static const struct i2c_device_id ub960_id[] = { >>> + { "ds90ub954-q1", (kernel_ulong_t)&ds90ub954_hw }, >>> { "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw }, >>> { "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw }, >>> {} >>> @@ -5199,6 +5244,7 @@ static const struct i2c_device_id ub960_id[] = { >>> MODULE_DEVICE_TABLE(i2c, ub960_id); >>> static const struct of_device_id ub960_dt_ids[] = { >>> + { .compatible = "ti,ds90ub954-q1", .data = &ds90ub954_hw }, >>> { .compatible = "ti,ds90ub960-q1", .data = &ds90ub960_hw }, >>> { .compatible = "ti,ds90ub9702-q1", .data = &ds90ub9702_hw }, >>> {} >> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 2025-06-02 7:16 ` Tomi Valkeinen @ 2025-06-02 10:54 ` Yemike Abhilash Chandra 0 siblings, 0 replies; 9+ messages in thread From: Yemike Abhilash Chandra @ 2025-06-02 10:54 UTC (permalink / raw) To: Tomi Valkeinen Cc: hverkuil, sakari.ailus, laurent.pinchart, vaishnav.a, u-kumar1, jai.luthra, linux-media, devicetree, linux-kernel, mchehab, robh, krzk+dt, conor+dt Hi Tomi, Thanks for the review. On 02/06/25 12:46, Tomi Valkeinen wrote: > Hi, > > On 28/05/2025 09:25, Yemike Abhilash Chandra wrote: >> Hi Tomi, >> >> Thanks for the review. >> >> On 27/05/25 11:10, Tomi Valkeinen wrote: >>> Hi, >>> >>> On 23/05/2025 11:36, Yemike Abhilash Chandra wrote: >>>> DS90UB954-Q1 is an FPDLink-III deserializer that is mostly register >>>> compatible with DS90UB960-Q1. The main difference is that it supports >>>> half of the RX and TX ports, i.e. 2x FPDLink RX ports and 1x CSI TX >>>> port. >>>> >>>> Some other registers are marked as reserved in the datasheet as well, >>>> notably around CSI-TX frame and line-count monitoring and some other >>> >>> Hmm what does that mean? That in log_status we show random data (or >>> maybe always 0) for these? >>> >> >> It seems like it is showing 0's for these. I streamed around 100 frames. >> But the frame counter and line counter returned is 0. Please find the >> logs at [1]. > > If the registers are marked as reserved and don't function, we should > not use them. Here it doesn't do any harm when running the code, but it > does decrease the usefulness of log_status if the user is shown data > that is wrong (and the user most likely doesn't know it's wrong). > Yes, Understood. I will address this in the next revision. >>>> status registers. The datasheet also does not mention anything about >>>> setting strobe position, and fails to lock the RX ports if we forcefully >>>> set it, so disable it through the hw_data. >>> >>> This app-note has some details: >>> >>> https://www.ti.com/lit/an/snla301/snla301.pdf >>> >>>> Link: https://www.ti.com/lit/gpn/ds90ub954-q1 >>>> Signed-off-by: Yemike Abhilash Chandra <y-abhilashchandra@ti.com> >>>> --- >>>> drivers/media/i2c/Kconfig | 2 +- >>>> drivers/media/i2c/ds90ub960.c | 46 +++++++++++++++++++++++++++++++++++ >>>> 2 files changed, 47 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig >>>> index e68202954a8f..6e265e1cec20 100644 >>>> --- a/drivers/media/i2c/Kconfig >>>> +++ b/drivers/media/i2c/Kconfig >>>> @@ -1662,7 +1662,7 @@ config VIDEO_DS90UB960 >>>> select V4L2_FWNODE >>>> select VIDEO_V4L2_SUBDEV_API >>>> help >>>> - Device driver for the Texas Instruments DS90UB960 >>>> + Device driver for the Texas Instruments DS90UB954/DS90UB960 >>>> FPD-Link III Deserializer and DS90UB9702 FPD-Link IV >>>> Deserializer. >>>> config VIDEO_MAX96714 >>>> diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ >>>> ds90ub960.c >>>> index ed2cf9d247d1..38e4f006d098 100644 >>>> --- a/drivers/media/i2c/ds90ub960.c >>>> +++ b/drivers/media/i2c/ds90ub960.c >>>> @@ -460,6 +460,7 @@ struct ub960_hw_data { >>>> u8 num_txports; >>>> bool is_ub9702; >>>> bool is_fpdlink4; >>>> + bool is_ub954; >>> >>> No, let's not add any more of these. We should have enums for the device >>> model and the "family" (ub954/ub960 are clearly of the same family, >>> whereas ub9702 is of a newer one). >>> >> >> Got it. I will add enums in the next revision. >> >>>> }; >>>> enum ub960_rxport_mode { >>>> @@ -982,6 +983,10 @@ static int ub960_txport_select(struct ub960_data >>>> *priv, u8 nport) >>>> lockdep_assert_held(&priv->reg_lock); >>>> + /* TX port registers are shared for UB954*/ >>> >>> Space missing at the end. What does the comment mean? "registers are >>> shared"? >>> >> >> Apologies for the inaccurate comment description, My intention to >> comment that the tx_port_select function does not make sense for >> UB954, since we have only 1 CSI TX. May be I can have something >> like below. >> >> /** UB954 has only 1 CSI TX. Hence, no need to select **/ >> >>> I think it's good to have this after the lockdep assert. The lock rules >>> are in place, even if on ub954 we don't do anything here. >>> >>>> + if (priv->hw_data->is_ub954) >>>> + return 0; >>>> + >>>> if (priv->reg_current.txport == nport) >>>> return 0; >>>> @@ -1415,6 +1420,13 @@ static int ub960_parse_dt_txport(struct >>>> ub960_data *priv, >>>> goto err_free_vep; >>>> } >>>> + /* UB954 does not support 1.2 Gbps */ >>>> + if (priv->tx_data_rate == MHZ(1200) && priv->hw_data->is_ub954) { >>> >>> Test for ub954 first, 1200 MHz second. It's more logical for the reader >>> that way. >>> >> >> Noted, will do that in the next revision. >> >>>> + dev_err(dev, "tx%u: invalid 'link-frequencies' value\n", >>>> nport); >>>> + ret = -EINVAL; >>>> + goto err_free_vep; >>>> + } >>>> + >>>> v4l2_fwnode_endpoint_free(&vep); >>>> priv->txports[nport] = txport; >>>> @@ -1572,6 +1584,10 @@ static int ub960_rxport_set_strobe_pos(struct >>>> ub960_data *priv, >>>> u8 clk_delay, data_delay; >>>> int ret = 0; >>>> + /* FIXME: After writing to this area the UB954 chip no longer >>>> responds */ >>>> + if (priv->hw_data->is_ub954) >>>> + return 0; >>>> + >>> >>> Check the app note. It would be nice to have this working, as, afaik, >>> the HW functionality should be the same on ub954 and ub960. >>> >> >> I tried referring the app note and changed the strobe position values >> accordingly, but it did not help. >> >> Since the app note also specifies the below at Table 2 Strobe Adaption >> Modes >> >> " >> AEQ Adaption Mode--> Strobe position is selected as part of AEQ. This is >> the default mode. >> >> Manual Adaption Mode --> The strobe position is selected manually and >> will remain at >> the specified position until a new one is chosen. This mode is >> recommended as an >> evaluation and debugging mode " >> >> Since, under the default settings, the strobe position is selected as >> part of the AEQ process. >> Can we limit the ub960_rxport_set_strobe_pos function to only UB960 and >> UB9702. > > Ok. But it doesn't sound good if we just skip the > ub960_rxport_set_strobe_pos(), but keep all the other EQ related writes. > I.e. we do the EQ config partially, and leave out parts that, for > unknown reasons, seem to cause problems... > > So probably the check should be in ub960_rxport_config_eq(). With a > FIXME comment, and a short note where it fails. > > That said, if everyone (?) agrees that the HW should support this, it > would be really nice if you can keep poking the FPD-Link people in TI > and try to get clarification on what's going on (what's the diff between > ub960 and ub954). > Yes, I will do that. > Btw, did you look at the other EQ related writes, and check if they're > valid for ub954? > Not until now, will check that. Thanks and Regards Abhilash Chandra > Tomi > >>>> clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY; >>>> data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY; >>>> @@ -5021,6 +5037,27 @@ static int ub960_enable_core_hw(struct >>>> ub960_data *priv) >>>> if (priv->hw_data->is_ub9702) >>>> ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq, >>>> NULL); >>>> + else if (priv->hw_data->is_ub954) { >>>> + /* From DS90UB954-Q1 datasheet: >>>> + * "REFCLK_FREQ measurement is not synchronized. Value in this >>>> + * register should read twice and only considered valid if >>>> + * REFCLK_FREQ is unchanged between reads." >>>> + */ >>>> + unsigned long timeout = jiffies + msecs_to_jiffies(100); >>>> + >>>> + do { >>>> + u8 refclk_new; >>>> + >>>> + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_new, >>>> + NULL); >>>> + if (ret) >>>> + goto err_pd_gpio; >>>> + >>>> + if (refclk_new == refclk_freq) >>>> + break; >>>> + refclk_freq = refclk_new; >>>> + } while (time_before(jiffies, timeout)); >>>> + } >>> >>> This feels a bit too much for a not-that-important debug print... As the >>> tests show that a single read is (practically always?) enough, I think >>> we can just use the same code as for ub960. Maybe add a comment about >>> it, though. >>> >> >> okay, I will use the same code that is being used for UB960 and will add >> a comment >> about that. >> >> Thanks and Regards, >> Abhilash Chandra >> >> [1]: https://gist.github.com/Yemike-Abhilash-Chandra/ >> c6b3da2a10586567a3a4179a2b20d21b >> >>> Tomi >>> >>>> else >>>> ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq, >>>> NULL); >>>> @@ -5177,6 +5214,13 @@ static void ub960_remove(struct i2c_client >>>> *client) >>>> mutex_destroy(&priv->reg_lock); >>>> } >>>> +static const struct ub960_hw_data ds90ub954_hw = { >>>> + .model = "ub954", >>>> + .num_rxports = 2, >>>> + .num_txports = 1, >>>> + .is_ub954 = true, >>>> +}; >>>> + >>>> static const struct ub960_hw_data ds90ub960_hw = { >>>> .model = "ub960", >>>> .num_rxports = 4, >>>> @@ -5192,6 +5236,7 @@ static const struct ub960_hw_data ds90ub9702_hw >>>> = { >>>> }; >>>> static const struct i2c_device_id ub960_id[] = { >>>> + { "ds90ub954-q1", (kernel_ulong_t)&ds90ub954_hw }, >>>> { "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw }, >>>> { "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw }, >>>> {} >>>> @@ -5199,6 +5244,7 @@ static const struct i2c_device_id ub960_id[] = { >>>> MODULE_DEVICE_TABLE(i2c, ub960_id); >>>> static const struct of_device_id ub960_dt_ids[] = { >>>> + { .compatible = "ti,ds90ub954-q1", .data = &ds90ub954_hw }, >>>> { .compatible = "ti,ds90ub960-q1", .data = &ds90ub960_hw }, >>>> { .compatible = "ti,ds90ub9702-q1", .data = &ds90ub9702_hw }, >>>> {} >>> > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-06-04 16:42 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-06-04 15:45 [PATCH 2/2] media: i2c: ds90ub960: Add support for DS90UB954-Q1 kernel test robot 2025-06-04 16:42 ` Dan Carpenter -- strict thread matches above, loose matches on Subject: below -- 2025-05-23 8:36 [PATCH 0/2] " Yemike Abhilash Chandra 2025-05-23 8:36 ` [PATCH 2/2] media: i2c: ds90ub960: " Yemike Abhilash Chandra 2025-05-23 16:53 ` Jai Luthra 2025-05-26 6:24 ` Yemike Abhilash Chandra 2025-05-27 5:40 ` Tomi Valkeinen 2025-05-28 6:25 ` Yemike Abhilash Chandra 2025-06-02 7:16 ` Tomi Valkeinen 2025-06-02 10:54 ` Yemike Abhilash Chandra
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.