Lines Matching +full:dclk +full:- +full:div
1 // SPDX-License-Identifier: GPL-2.0
3 * LMK04832 Ultra Low-Noise JESD204B Compliant Clock Jitter Cleaner
14 #include <linux/clk-provider.h>
22 /* 0x000 - 0x00d System Functions */
34 /* 0x100 - 0x137 Device Clock and SYSREF Clock Output Control */
75 /* 0x138 - 0x145 SYSREF, SYNC, and Device Config */
124 /* 0x146 - 0x14a CLKin Control */
134 /* 0x14b - 0x152 Holdover */
136 /* 0x153 - 0x15f PLL1 Configuration */
143 /* 0x160 - 0x16e PLL2 Configuration */
166 /* 0x16F - 0x555 Misc Registers */
183 * struct lmk04832_device_info - Holds static device information that is
232 * struct lmk04832 - The LMK04832 device structure
246 * @dclk: list of internal device clock references.
267 struct lmk_dclk *dclk;
334 ret = regmap_read(lmk->regmap, LMK04832_REG_MAIN_PD, &tmp);
348 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_PD,
355 return regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD,
365 regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_PD,
370 regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD,
385 ret = regmap_read(lmk->regmap, LMK04832_REG_PLL2_MISC, &pll2_misc);
391 ret = regmap_bulk_read(lmk->regmap, LMK04832_REG_PLL2_N_0, &tmp, 3);
399 ret = regmap_bulk_read(lmk->regmap, LMK04832_REG_PLL2_R_MSB, &tmp, 2);
413 * lmk04832_check_vco_ranges - Check requested VCO frequency against VCO ranges
425 struct spi_device *spi = to_spi_device(lmk->dev);
429 info = &lmk04832_device_info[spi_get_device_id(spi)->driver_data];
431 if (mhz >= info->vco0_range[0] && mhz <= info->vco0_range[1])
434 if (mhz >= info->vco1_range[0] && mhz <= info->vco1_range[1])
437 dev_err(lmk->dev, "%lu Hz is out of VCO ranges\n", rate);
438 return -ERANGE;
442 * lmk04832_calc_pll2_params - Get PLL2 parameters used to set the VCO frequency
465 unsigned long num, div;
470 div = gcd(rate, prate);
472 num = DIV_ROUND_CLOSEST(rate, div);
473 pll2_r = DIV_ROUND_CLOSEST(prate, div);
483 return -EINVAL;
485 return -EINVAL;
508 dev_err(lmk->dev, "PLL2 parameters out of range\n");
513 return -EINVAL;
531 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_VCO_OSCOUT,
539 dev_err(lmk->dev, "failed to determine PLL2 parameters\n");
543 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_R_MSB,
549 ret = regmap_write(lmk->regmap, LMK04832_REG_PLL2_R_LSB,
554 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_MISC,
564 ret = regmap_write(lmk->regmap, LMK04832_REG_PLL2_N_0,
568 ret = regmap_write(lmk->regmap, LMK04832_REG_PLL2_N_1,
573 return regmap_write(lmk->regmap, LMK04832_REG_PLL2_N_2,
587 * lmk04832_register_vco - Initialize the internal VCO and clock distribution
596 init.name = "lmk-vco";
597 parent_names[0] = __clk_get_name(lmk->oscin);
603 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_VCO_OSCOUT,
610 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_FB_CTRL,
620 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_MISC,
626 ret = regmap_write(lmk->regmap, LMK04832_REG_PLL2_LD,
634 lmk->vco.init = &init;
635 return devm_clk_hw_register(lmk->dev, &lmk->vco);
640 static const int dclk_div_adj[] = {0, 0, -2, -2, 0, 3, -1, 0};
649 ret = regmap_update_bits(lmk->regmap,
656 ret = regmap_read(lmk->regmap, LMK04832_REG_SYSREF_DDLY_LSB, &lsb);
660 ret = regmap_read(lmk->regmap, LMK04832_REG_SYSREF_DDLY_MSB, &msb);
666 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL0(id), &lsb);
670 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL2(id), &msb);
676 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL3(id), &lsb);
682 dclkx_y_ddly = sysref_ddly + 1 -
683 dclk_div_adj[dclkx_y_div < 6 ? dclkx_y_div : 7] -
687 dev_err(lmk->dev, "DCLKX_Y_DDLY out of range (%d)\n",
689 return -EINVAL;
692 ret = regmap_write(lmk->regmap,
698 ret = regmap_write(lmk->regmap, LMK04832_REG_CLKOUT_CTRL1(id),
703 dev_dbg(lmk->dev, "clkout%02u: sysref_ddly=%u, dclkx_y_ddly=%u, "
709 return regmap_update_bits(lmk->regmap, LMK04832_REG_CLKOUT_CTRL2(id),
714 /** lmk04832_sclk_sync - Establish deterministic phase relationship between sclk
715 * and dclk
720 * - in the datasheet https://www.ti.com/lit/ds/symlink/lmk04832.pdf, p.31
722 * - Ti forum: https://e2e.ti.com/support/clock-and-timing/f/48/t/970972
733 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD,
739 for (i = 0; i < lmk->clk_data->num; i += 2) {
749 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYSREF_OUT,
758 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC,
766 ret = regmap_write(lmk->regmap, LMK04832_REG_SYNC_DIS, 0x00);
773 * PLL2-only use case, this will be complete in less than one SPI
777 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC,
783 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC,
795 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC,
801 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC,
808 ret = regmap_write(lmk->regmap, LMK04832_REG_SYNC_DIS, 0xff);
813 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYSREF_OUT,
816 lmk->sysref_mux));
820 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC,
823 lmk->sync_mode));
850 ret = regmap_read(lmk->regmap, LMK04832_REG_MAIN_PD, &tmp);
861 return regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD,
869 regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD,
881 ret = regmap_bulk_read(lmk->regmap, LMK04832_REG_SYSREF_DIV_MSB, &tmp, 2);
902 dev_err(lmk->dev, "SYSREF divider out of range\n");
903 return -EINVAL;
907 return -EINVAL;
922 dev_err(lmk->dev, "SYSREF divider out of range\n");
923 return -EINVAL;
926 ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_DIV_MSB,
931 ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_DIV_LSB,
938 dev_err(lmk->dev, "SYNC sequence failed\n");
958 init.name = "lmk-sclk";
959 parent_names[0] = clk_hw_get_name(&lmk->vco);
966 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYSREF_OUT,
969 lmk->sysref_mux));
973 ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_DDLY_LSB,
974 FIELD_GET(0x00ff, lmk->sysref_ddly));
978 ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_DDLY_MSB,
979 FIELD_GET(0x1f00, lmk->sysref_ddly));
983 ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_PULSE_CNT,
984 ilog2(lmk->sysref_pulse_cnt));
988 ret = regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD,
996 ret = regmap_write(lmk->regmap, LMK04832_REG_SYNC,
999 FIELD_PREP(LMK04832_BIT_SYNC_MODE, lmk->sync_mode));
1003 ret = regmap_write(lmk->regmap, LMK04832_REG_SYNC_DIS, 0xff);
1007 lmk->sclk.init = &init;
1008 return devm_clk_hw_register(lmk->dev, &lmk->sclk);
1013 struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw);
1014 struct lmk04832 *lmk = dclk->lmk;
1018 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL3(dclk->id),
1028 struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw);
1029 struct lmk04832 *lmk = dclk->lmk;
1031 return regmap_update_bits(lmk->regmap,
1032 LMK04832_REG_CLKOUT_CTRL3(dclk->id),
1038 struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw);
1039 struct lmk04832 *lmk = dclk->lmk;
1041 regmap_update_bits(lmk->regmap,
1042 LMK04832_REG_CLKOUT_CTRL3(dclk->id),
1049 struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw);
1050 struct lmk04832 *lmk = dclk->lmk;
1056 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL0(dclk->id),
1061 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL2(dclk->id),
1075 struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw);
1076 struct lmk04832 *lmk = dclk->lmk;
1084 dev_err(lmk->dev, "%s_div out of range\n", clk_hw_get_name(hw));
1085 return -EINVAL;
1089 return -EINVAL;
1097 struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw);
1098 struct lmk04832 *lmk = dclk->lmk;
1105 dev_err(lmk->dev, "%s_div out of range\n", clk_hw_get_name(hw));
1106 return -EINVAL;
1111 ret = regmap_update_bits(lmk->regmap,
1112 LMK04832_REG_CLKOUT_CTRL3(dclk->id),
1120 * While using Divide-by-2 or Divide-by-3 for DCLK_X_Y_DIV, SYNC
1121 * procedure requires to first program Divide-by-4 and then back to
1122 * Divide-by-2 or Divide-by-3 before doing SYNC.
1125 ret = regmap_update_bits(lmk->regmap,
1126 LMK04832_REG_CLKOUT_CTRL2(dclk->id),
1131 ret = regmap_write(lmk->regmap,
1132 LMK04832_REG_CLKOUT_CTRL0(dclk->id), 0x04);
1137 ret = regmap_write(lmk->regmap, LMK04832_REG_CLKOUT_CTRL0(dclk->id),
1142 ret = regmap_update_bits(lmk->regmap,
1143 LMK04832_REG_CLKOUT_CTRL2(dclk->id),
1151 dev_err(lmk->dev, "SYNC sequence failed\n");
1168 struct lmk04832 *lmk = clkout->lmk;
1176 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL2(clkout->id),
1183 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_SRC_MUX(clkout->id),
1189 ret = regmap_read(lmk->regmap,
1190 LMK04832_REG_CLKOUT_CTRL4(clkout->id),
1198 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_FMT(clkout->id),
1203 if (clkout->id % 2)
1214 struct lmk04832 *lmk = clkout->lmk;
1218 if (clkout->format == LMK04832_VAL_CLKOUT_FMT_POWERDOWN)
1219 dev_err(lmk->dev, "prepared %s but format is powerdown\n",
1222 ret = regmap_update_bits(lmk->regmap,
1223 LMK04832_REG_CLKOUT_CTRL2(clkout->id),
1228 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_SRC_MUX(clkout->id),
1234 ret = regmap_update_bits(lmk->regmap,
1235 LMK04832_REG_CLKOUT_CTRL4(clkout->id),
1241 return regmap_update_bits(lmk->regmap,
1242 LMK04832_REG_CLKOUT_FMT(clkout->id),
1243 LMK04832_BIT_CLKOUT_FMT(clkout->id),
1244 clkout->format << 4 * (clkout->id % 2));
1250 struct lmk04832 *lmk = clkout->lmk;
1252 regmap_update_bits(lmk->regmap, LMK04832_REG_CLKOUT_FMT(clkout->id),
1253 LMK04832_BIT_CLKOUT_FMT(clkout->id),
1260 struct lmk04832 *lmk = clkout->lmk;
1262 return regmap_update_bits(lmk->regmap,
1263 LMK04832_REG_CLKOUT_SRC_MUX(clkout->id),
1272 struct lmk04832 *lmk = clkout->lmk;
1276 ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_SRC_MUX(clkout->id),
1295 char name[] = "lmk-clkoutXX";
1296 char dclk_name[] = "lmk-dclkXX_YY";
1303 sprintf(dclk_name, "lmk-dclk%02d_%02d", num, num + 1);
1305 parent_names[0] = clk_hw_get_name(&lmk->vco);
1311 lmk->dclk[dclk_num].id = num;
1312 lmk->dclk[dclk_num].lmk = lmk;
1313 lmk->dclk[dclk_num].hw.init = &init;
1315 ret = devm_clk_hw_register(lmk->dev, &lmk->dclk[dclk_num].hw);
1319 sprintf(dclk_name, "lmk-dclk%02d_%02d", num - 1, num);
1322 if (of_property_read_string_index(lmk->dev->of_node,
1323 "clock-output-names",
1325 sprintf(name, "lmk-clkout%02d", num);
1330 parent_names[1] = clk_hw_get_name(&lmk->sclk);
1336 lmk->clkout[num].id = num;
1337 lmk->clkout[num].lmk = lmk;
1338 lmk->clkout[num].hw.init = &init;
1339 lmk->clk_data->hws[num] = &lmk->clkout[num].hw;
1342 regmap_update_bits(lmk->regmap,
1346 lmk->clkout[num].sysref));
1348 return devm_clk_hw_register(lmk->dev, &lmk->clkout[num].hw);
1360 dev_info(lmk->dev, "setting up 4-wire mode\n");
1361 ret = regmap_write(lmk->regmap, LMK04832_REG_RST3W,
1384 return -EINVAL;
1387 return regmap_write(lmk->regmap, reg, val);
1400 info = &lmk04832_device_info[spi_get_device_id(spi)->driver_data];
1402 lmk = devm_kzalloc(&spi->dev, sizeof(struct lmk04832), GFP_KERNEL);
1404 return -ENOMEM;
1406 lmk->dev = &spi->dev;
1408 lmk->oscin = devm_clk_get_enabled(lmk->dev, "oscin");
1409 if (IS_ERR(lmk->oscin)) {
1410 dev_err(lmk->dev, "failed to get oscin clock\n");
1411 return PTR_ERR(lmk->oscin);
1414 lmk->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
1417 lmk->dclk = devm_kcalloc(lmk->dev, info->num_channels >> 1,
1419 if (!lmk->dclk) {
1420 ret = -ENOMEM;
1424 lmk->clkout = devm_kcalloc(lmk->dev, info->num_channels,
1425 sizeof(*lmk->clkout), GFP_KERNEL);
1426 if (!lmk->clkout) {
1427 ret = -ENOMEM;
1431 lmk->clk_data = devm_kzalloc(lmk->dev, struct_size(lmk->clk_data, hws,
1432 info->num_channels),
1434 if (!lmk->clk_data) {
1435 ret = -ENOMEM;
1439 device_property_read_u32(lmk->dev, "ti,vco-hz", &lmk->vco_rate);
1441 lmk->sysref_ddly = 8;
1442 device_property_read_u32(lmk->dev, "ti,sysref-ddly", &lmk->sysref_ddly);
1444 lmk->sysref_mux = LMK04832_VAL_SYSREF_MUX_CONTINUOUS;
1445 device_property_read_u32(lmk->dev, "ti,sysref-mux",
1446 &lmk->sysref_mux);
1448 lmk->sync_mode = LMK04832_VAL_SYNC_MODE_OFF;
1449 device_property_read_u32(lmk->dev, "ti,sync-mode",
1450 &lmk->sync_mode);
1452 lmk->sysref_pulse_cnt = 4;
1453 device_property_read_u32(lmk->dev, "ti,sysref-pulse-count",
1454 &lmk->sysref_pulse_cnt);
1456 for_each_child_of_node(lmk->dev->of_node, child) {
1461 dev_err(lmk->dev, "missing reg property in child: %s\n",
1462 child->full_name);
1467 of_property_read_u32(child, "ti,clkout-fmt",
1468 &lmk->clkout[reg].format);
1470 if (lmk->clkout[reg].format >= 0x0a && reg % 2 == 0
1472 dev_err(lmk->dev, "invalid format for clkout%02d\n",
1475 lmk->clkout[reg].sysref =
1476 of_property_read_bool(child, "ti,clkout-sysref");
1479 lmk->regmap = devm_regmap_init_spi(spi, ®map_config);
1480 if (IS_ERR(lmk->regmap)) {
1481 dev_err(lmk->dev, "%s: regmap allocation failed: %ld\n",
1483 __func__, PTR_ERR(lmk->regmap));
1484 ret = PTR_ERR(lmk->regmap);
1488 regmap_write(lmk->regmap, LMK04832_REG_RST3W, LMK04832_BIT_RESET);
1490 if (!(spi->mode & SPI_3WIRE)) {
1491 device_property_read_u32(lmk->dev, "ti,spi-4wire-rdbk",
1498 regmap_bulk_read(lmk->regmap, LMK04832_REG_ID_PROD_MSB, &tmp, 3);
1499 if ((tmp[0] << 8 | tmp[1]) != info->pid || tmp[2] != info->maskrev) {
1500 dev_err(lmk->dev, "unsupported device type: pid 0x%04x, maskrev 0x%02x\n",
1502 ret = -EINVAL;
1508 dev_err(lmk->dev, "failed to init device clock path\n");
1512 if (lmk->vco_rate) {
1513 dev_info(lmk->dev, "setting VCO rate to %u Hz\n", lmk->vco_rate);
1514 ret = clk_set_rate(lmk->vco.clk, lmk->vco_rate);
1516 dev_err(lmk->dev, "failed to set VCO rate\n");
1523 dev_err(lmk->dev, "failed to init SYNC/SYSREF clock path\n");
1527 for (i = 0; i < info->num_channels; i++) {
1530 dev_err(lmk->dev, "failed to register clk %d\n", i);
1535 lmk->clk_data->num = info->num_channels;
1536 ret = devm_of_clk_add_hw_provider(lmk->dev, of_clk_hw_onecell_get,
1537 lmk->clk_data);
1539 dev_err(lmk->dev, "failed to add provider (%d)\n", ret);