2478 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * PTP hardware clock driver for the IDT ClockMatrix(TM) family of timing and4 * synchronization devices.5 *6 * Copyright (C) 2019 Integrated Device Technology, Inc., a Renesas Company.7 */8#include <linux/firmware.h>9#include <linux/platform_device.h>10#include <linux/module.h>11#include <linux/ptp_clock_kernel.h>12#include <linux/delay.h>13#include <linux/jiffies.h>14#include <linux/kernel.h>15#include <linux/timekeeping.h>16#include <linux/string.h>17#include <linux/of.h>18#include <linux/mfd/rsmu.h>19#include <linux/mfd/idt8a340_reg.h>20#include <linux/unaligned.h>21 22#include "ptp_private.h"23#include "ptp_clockmatrix.h"24 25MODULE_DESCRIPTION("Driver for IDT ClockMatrix(TM) family");26MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");27MODULE_AUTHOR("IDT support-1588 <IDT-support-1588@lm.renesas.com>");28MODULE_VERSION("1.0");29MODULE_LICENSE("GPL");30 31/*32 * The name of the firmware file to be loaded33 * over-rides any automatic selection34 */35static char *firmware;36module_param(firmware, charp, 0);37 38#define SETTIME_CORRECTION (0)39#define EXTTS_PERIOD_MS (95)40 41static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm);42 43static inline int idtcm_read(struct idtcm *idtcm,44 u16 module,45 u16 regaddr,46 u8 *buf,47 u16 count)48{49 return regmap_bulk_read(idtcm->regmap, module + regaddr, buf, count);50}51 52static inline int idtcm_write(struct idtcm *idtcm,53 u16 module,54 u16 regaddr,55 u8 *buf,56 u16 count)57{58 return regmap_bulk_write(idtcm->regmap, module + regaddr, buf, count);59}60 61static int contains_full_configuration(struct idtcm *idtcm,62 const struct firmware *fw)63{64 struct idtcm_fwrc *rec = (struct idtcm_fwrc *)fw->data;65 u16 scratch = IDTCM_FW_REG(idtcm->fw_ver, V520, SCRATCH);66 s32 full_count;67 s32 count = 0;68 u16 regaddr;69 u8 loaddr;70 s32 len;71 72 /* 4 bytes skipped every 0x80 */73 full_count = (scratch - GPIO_USER_CONTROL) -74 ((scratch >> 7) - (GPIO_USER_CONTROL >> 7)) * 4;75 76 /* If the firmware contains 'full configuration' SM_RESET can be used77 * to ensure proper configuration.78 *79 * Full configuration is defined as the number of programmable80 * bytes within the configuration range minus page offset addr range.81 */82 for (len = fw->size; len > 0; len -= sizeof(*rec)) {83 regaddr = rec->hiaddr << 8;84 regaddr |= rec->loaddr;85 86 loaddr = rec->loaddr;87 88 rec++;89 90 /* Top (status registers) and bottom are read-only */91 if (regaddr < GPIO_USER_CONTROL || regaddr >= scratch)92 continue;93 94 /* Page size 128, last 4 bytes of page skipped */95 if ((loaddr > 0x7b && loaddr <= 0x7f) || loaddr > 0xfb)96 continue;97 98 count++;99 }100 101 return (count >= full_count);102}103 104static int char_array_to_timespec(u8 *buf,105 u8 count,106 struct timespec64 *ts)107{108 u8 i;109 u64 nsec;110 time64_t sec;111 112 if (count < TOD_BYTE_COUNT)113 return 1;114 115 /* Sub-nanoseconds are in buf[0]. */116 nsec = buf[4];117 for (i = 0; i < 3; i++) {118 nsec <<= 8;119 nsec |= buf[3 - i];120 }121 122 sec = buf[10];123 for (i = 0; i < 5; i++) {124 sec <<= 8;125 sec |= buf[9 - i];126 }127 128 ts->tv_sec = sec;129 ts->tv_nsec = nsec;130 131 return 0;132}133 134static int timespec_to_char_array(struct timespec64 const *ts,135 u8 *buf,136 u8 count)137{138 u8 i;139 s32 nsec;140 time64_t sec;141 142 if (count < TOD_BYTE_COUNT)143 return 1;144 145 nsec = ts->tv_nsec;146 sec = ts->tv_sec;147 148 /* Sub-nanoseconds are in buf[0]. */149 buf[0] = 0;150 for (i = 1; i < 5; i++) {151 buf[i] = nsec & 0xff;152 nsec >>= 8;153 }154 155 for (i = 5; i < TOD_BYTE_COUNT; i++) {156 157 buf[i] = sec & 0xff;158 sec >>= 8;159 }160 161 return 0;162}163 164static int idtcm_strverscmp(const char *version1, const char *version2)165{166 u8 ver1[3], ver2[3];167 int i;168 169 if (sscanf(version1, "%hhu.%hhu.%hhu",170 &ver1[0], &ver1[1], &ver1[2]) != 3)171 return -1;172 if (sscanf(version2, "%hhu.%hhu.%hhu",173 &ver2[0], &ver2[1], &ver2[2]) != 3)174 return -1;175 176 for (i = 0; i < 3; i++) {177 if (ver1[i] > ver2[i])178 return 1;179 if (ver1[i] < ver2[i])180 return -1;181 }182 183 return 0;184}185 186static enum fw_version idtcm_fw_version(const char *version)187{188 enum fw_version ver = V_DEFAULT;189 190 if (idtcm_strverscmp(version, "4.8.7") >= 0)191 ver = V487;192 193 if (idtcm_strverscmp(version, "5.2.0") >= 0)194 ver = V520;195 196 return ver;197}198 199static int clear_boot_status(struct idtcm *idtcm)200{201 u8 buf[4] = {0};202 203 return idtcm_write(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, sizeof(buf));204}205 206static int read_boot_status(struct idtcm *idtcm, u32 *status)207{208 int err;209 u8 buf[4] = {0};210 211 err = idtcm_read(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, sizeof(buf));212 213 *status = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];214 215 return err;216}217 218static int wait_for_boot_status_ready(struct idtcm *idtcm)219{220 u32 status = 0;221 u8 i = 30; /* 30 * 100ms = 3s */222 int err;223 224 do {225 err = read_boot_status(idtcm, &status);226 if (err)227 return err;228 229 if (status == 0xA0)230 return 0;231 232 msleep(100);233 i--;234 235 } while (i);236 237 dev_warn(idtcm->dev, "%s timed out", __func__);238 239 return -EBUSY;240}241 242static int arm_tod_read_trig_sel_refclk(struct idtcm_channel *channel, u8 ref)243{244 struct idtcm *idtcm = channel->idtcm;245 u16 tod_read_cmd = IDTCM_FW_REG(idtcm->fw_ver, V520, TOD_READ_SECONDARY_CMD);246 u8 val = 0;247 int err;248 249 val &= ~(WR_REF_INDEX_MASK << WR_REF_INDEX_SHIFT);250 val |= (ref << WR_REF_INDEX_SHIFT);251 252 err = idtcm_write(idtcm, channel->tod_read_secondary,253 TOD_READ_SECONDARY_SEL_CFG_0, &val, sizeof(val));254 if (err)255 return err;256 257 val = 0 | (SCSR_TOD_READ_TRIG_SEL_REFCLK << TOD_READ_TRIGGER_SHIFT);258 259 err = idtcm_write(idtcm, channel->tod_read_secondary, tod_read_cmd,260 &val, sizeof(val));261 if (err)262 dev_err(idtcm->dev, "%s: err = %d", __func__, err);263 264 return err;265}266 267static bool is_single_shot(u8 mask)268{269 /* Treat single bit ToD masks as continuous trigger */270 return !(mask <= 8 && is_power_of_2(mask));271}272 273static int idtcm_extts_enable(struct idtcm_channel *channel,274 struct ptp_clock_request *rq, int on)275{276 u8 index = rq->extts.index;277 struct idtcm *idtcm;278 u8 mask = 1 << index;279 int err = 0;280 u8 old_mask;281 int ref;282 283 idtcm = channel->idtcm;284 old_mask = idtcm->extts_mask;285 286 /* Reject requests with unsupported flags */287 if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |288 PTP_RISING_EDGE |289 PTP_FALLING_EDGE |290 PTP_STRICT_FLAGS))291 return -EOPNOTSUPP;292 293 /* Reject requests to enable time stamping on falling edge */294 if ((rq->extts.flags & PTP_ENABLE_FEATURE) &&295 (rq->extts.flags & PTP_FALLING_EDGE))296 return -EOPNOTSUPP;297 298 if (index >= MAX_TOD)299 return -EINVAL;300 301 if (on) {302 /* Support triggering more than one TOD_0/1/2/3 by same pin */303 /* Use the pin configured for the channel */304 ref = ptp_find_pin(channel->ptp_clock, PTP_PF_EXTTS, channel->tod);305 306 if (ref < 0) {307 dev_err(idtcm->dev, "%s: No valid pin found for TOD%d!\n",308 __func__, channel->tod);309 return -EBUSY;310 }311 312 err = arm_tod_read_trig_sel_refclk(&idtcm->channel[index], ref);313 314 if (err == 0) {315 idtcm->extts_mask |= mask;316 idtcm->event_channel[index] = channel;317 idtcm->channel[index].refn = ref;318 idtcm->extts_single_shot = is_single_shot(idtcm->extts_mask);319 320 if (old_mask)321 return 0;322 323 schedule_delayed_work(&idtcm->extts_work,324 msecs_to_jiffies(EXTTS_PERIOD_MS));325 }326 } else {327 idtcm->extts_mask &= ~mask;328 idtcm->extts_single_shot = is_single_shot(idtcm->extts_mask);329 330 if (idtcm->extts_mask == 0)331 cancel_delayed_work(&idtcm->extts_work);332 }333 334 return err;335}336 337static int read_sys_apll_status(struct idtcm *idtcm, u8 *status)338{339 return idtcm_read(idtcm, STATUS, DPLL_SYS_APLL_STATUS, status,340 sizeof(u8));341}342 343static int read_sys_dpll_status(struct idtcm *idtcm, u8 *status)344{345 return idtcm_read(idtcm, STATUS, DPLL_SYS_STATUS, status, sizeof(u8));346}347 348static int wait_for_sys_apll_dpll_lock(struct idtcm *idtcm)349{350 unsigned long timeout = jiffies + msecs_to_jiffies(LOCK_TIMEOUT_MS);351 u8 apll = 0;352 u8 dpll = 0;353 int err;354 355 do {356 err = read_sys_apll_status(idtcm, &apll);357 if (err)358 return err;359 360 err = read_sys_dpll_status(idtcm, &dpll);361 if (err)362 return err;363 364 apll &= SYS_APLL_LOSS_LOCK_LIVE_MASK;365 dpll &= DPLL_SYS_STATE_MASK;366 367 if (apll == SYS_APLL_LOSS_LOCK_LIVE_LOCKED &&368 dpll == DPLL_STATE_LOCKED) {369 return 0;370 } else if (dpll == DPLL_STATE_FREERUN ||371 dpll == DPLL_STATE_HOLDOVER ||372 dpll == DPLL_STATE_OPEN_LOOP) {373 dev_warn(idtcm->dev,374 "No wait state: DPLL_SYS_STATE %d", dpll);375 return -EPERM;376 }377 378 msleep(LOCK_POLL_INTERVAL_MS);379 } while (time_is_after_jiffies(timeout));380 381 dev_warn(idtcm->dev,382 "%d ms lock timeout: SYS APLL Loss Lock %d SYS DPLL state %d",383 LOCK_TIMEOUT_MS, apll, dpll);384 385 return -ETIME;386}387 388static void wait_for_chip_ready(struct idtcm *idtcm)389{390 if (wait_for_boot_status_ready(idtcm))391 dev_warn(idtcm->dev, "BOOT_STATUS != 0xA0");392 393 if (wait_for_sys_apll_dpll_lock(idtcm))394 dev_warn(idtcm->dev,395 "Continuing while SYS APLL/DPLL is not locked");396}397 398static int _idtcm_gettime_triggered(struct idtcm_channel *channel,399 struct timespec64 *ts)400{401 struct idtcm *idtcm = channel->idtcm;402 u16 tod_read_cmd = IDTCM_FW_REG(idtcm->fw_ver, V520, TOD_READ_SECONDARY_CMD);403 u8 buf[TOD_BYTE_COUNT];404 u8 trigger;405 int err;406 407 err = idtcm_read(idtcm, channel->tod_read_secondary,408 tod_read_cmd, &trigger, sizeof(trigger));409 if (err)410 return err;411 412 if (trigger & TOD_READ_TRIGGER_MASK)413 return -EBUSY;414 415 err = idtcm_read(idtcm, channel->tod_read_secondary,416 TOD_READ_SECONDARY_BASE, buf, sizeof(buf));417 if (err)418 return err;419 420 return char_array_to_timespec(buf, sizeof(buf), ts);421}422 423static int _idtcm_gettime(struct idtcm_channel *channel,424 struct timespec64 *ts, u8 timeout)425{426 struct idtcm *idtcm = channel->idtcm;427 u16 tod_read_cmd = IDTCM_FW_REG(idtcm->fw_ver, V520, TOD_READ_PRIMARY_CMD);428 u8 buf[TOD_BYTE_COUNT];429 u8 trigger;430 int err;431 432 /* wait trigger to be 0 */433 do {434 if (timeout-- == 0)435 return -EIO;436 437 if (idtcm->calculate_overhead_flag)438 idtcm->start_time = ktime_get_raw();439 440 err = idtcm_read(idtcm, channel->tod_read_primary,441 tod_read_cmd, &trigger,442 sizeof(trigger));443 if (err)444 return err;445 } while (trigger & TOD_READ_TRIGGER_MASK);446 447 err = idtcm_read(idtcm, channel->tod_read_primary,448 TOD_READ_PRIMARY_BASE, buf, sizeof(buf));449 if (err)450 return err;451 452 err = char_array_to_timespec(buf, sizeof(buf), ts);453 454 return err;455}456 457static int idtcm_extts_check_channel(struct idtcm *idtcm, u8 todn)458{459 struct idtcm_channel *ptp_channel, *extts_channel;460 struct ptp_clock_event event;461 struct timespec64 ts;462 u32 dco_delay = 0;463 int err;464 465 extts_channel = &idtcm->channel[todn];466 ptp_channel = idtcm->event_channel[todn];467 468 if (extts_channel == ptp_channel)469 dco_delay = ptp_channel->dco_delay;470 471 err = _idtcm_gettime_triggered(extts_channel, &ts);472 if (err)473 return err;474 475 /* Triggered - save timestamp */476 event.type = PTP_CLOCK_EXTTS;477 event.index = todn;478 event.timestamp = timespec64_to_ns(&ts) - dco_delay;479 ptp_clock_event(ptp_channel->ptp_clock, &event);480 481 return err;482}483 484static int _idtcm_gettime_immediate(struct idtcm_channel *channel,485 struct timespec64 *ts)486{487 struct idtcm *idtcm = channel->idtcm;488 489 u16 tod_read_cmd = IDTCM_FW_REG(idtcm->fw_ver, V520, TOD_READ_PRIMARY_CMD);490 u8 val = (SCSR_TOD_READ_TRIG_SEL_IMMEDIATE << TOD_READ_TRIGGER_SHIFT);491 int err;492 493 err = idtcm_write(idtcm, channel->tod_read_primary,494 tod_read_cmd, &val, sizeof(val));495 if (err)496 return err;497 498 return _idtcm_gettime(channel, ts, 10);499}500 501static int _sync_pll_output(struct idtcm *idtcm,502 u8 pll,503 u8 sync_src,504 u8 qn,505 u8 qn_plus_1)506{507 int err;508 u8 val;509 u16 sync_ctrl0;510 u16 sync_ctrl1;511 u8 temp;512 513 if (qn == 0 && qn_plus_1 == 0)514 return 0;515 516 switch (pll) {517 case 0:518 sync_ctrl0 = HW_Q0_Q1_CH_SYNC_CTRL_0;519 sync_ctrl1 = HW_Q0_Q1_CH_SYNC_CTRL_1;520 break;521 case 1:522 sync_ctrl0 = HW_Q2_Q3_CH_SYNC_CTRL_0;523 sync_ctrl1 = HW_Q2_Q3_CH_SYNC_CTRL_1;524 break;525 case 2:526 sync_ctrl0 = HW_Q4_Q5_CH_SYNC_CTRL_0;527 sync_ctrl1 = HW_Q4_Q5_CH_SYNC_CTRL_1;528 break;529 case 3:530 sync_ctrl0 = HW_Q6_Q7_CH_SYNC_CTRL_0;531 sync_ctrl1 = HW_Q6_Q7_CH_SYNC_CTRL_1;532 break;533 case 4:534 sync_ctrl0 = HW_Q8_CH_SYNC_CTRL_0;535 sync_ctrl1 = HW_Q8_CH_SYNC_CTRL_1;536 break;537 case 5:538 sync_ctrl0 = HW_Q9_CH_SYNC_CTRL_0;539 sync_ctrl1 = HW_Q9_CH_SYNC_CTRL_1;540 break;541 case 6:542 sync_ctrl0 = HW_Q10_CH_SYNC_CTRL_0;543 sync_ctrl1 = HW_Q10_CH_SYNC_CTRL_1;544 break;545 case 7:546 sync_ctrl0 = HW_Q11_CH_SYNC_CTRL_0;547 sync_ctrl1 = HW_Q11_CH_SYNC_CTRL_1;548 break;549 default:550 return -EINVAL;551 }552 553 val = SYNCTRL1_MASTER_SYNC_RST;554 555 /* Place master sync in reset */556 err = idtcm_write(idtcm, 0, sync_ctrl1, &val, sizeof(val));557 if (err)558 return err;559 560 err = idtcm_write(idtcm, 0, sync_ctrl0, &sync_src, sizeof(sync_src));561 if (err)562 return err;563 564 /* Set sync trigger mask */565 val |= SYNCTRL1_FBDIV_FRAME_SYNC_TRIG | SYNCTRL1_FBDIV_SYNC_TRIG;566 567 if (qn)568 val |= SYNCTRL1_Q0_DIV_SYNC_TRIG;569 570 if (qn_plus_1)571 val |= SYNCTRL1_Q1_DIV_SYNC_TRIG;572 573 err = idtcm_write(idtcm, 0, sync_ctrl1, &val, sizeof(val));574 if (err)575 return err;576 577 /* PLL5 can have OUT8 as second additional output. */578 if (pll == 5 && qn_plus_1 != 0) {579 err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE,580 &temp, sizeof(temp));581 if (err)582 return err;583 584 temp &= ~(Q9_TO_Q8_SYNC_TRIG);585 586 err = idtcm_write(idtcm, 0, HW_Q8_CTRL_SPARE,587 &temp, sizeof(temp));588 if (err)589 return err;590 591 temp |= Q9_TO_Q8_SYNC_TRIG;592 593 err = idtcm_write(idtcm, 0, HW_Q8_CTRL_SPARE,594 &temp, sizeof(temp));595 if (err)596 return err;597 }598 599 /* PLL6 can have OUT11 as second additional output. */600 if (pll == 6 && qn_plus_1 != 0) {601 err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE,602 &temp, sizeof(temp));603 if (err)604 return err;605 606 temp &= ~(Q10_TO_Q11_SYNC_TRIG);607 608 err = idtcm_write(idtcm, 0, HW_Q11_CTRL_SPARE,609 &temp, sizeof(temp));610 if (err)611 return err;612 613 temp |= Q10_TO_Q11_SYNC_TRIG;614 615 err = idtcm_write(idtcm, 0, HW_Q11_CTRL_SPARE,616 &temp, sizeof(temp));617 if (err)618 return err;619 }620 621 /* Place master sync out of reset */622 val &= ~(SYNCTRL1_MASTER_SYNC_RST);623 err = idtcm_write(idtcm, 0, sync_ctrl1, &val, sizeof(val));624 625 return err;626}627 628static int idtcm_sync_pps_output(struct idtcm_channel *channel)629{630 struct idtcm *idtcm = channel->idtcm;631 u8 pll;632 u8 qn;633 u8 qn_plus_1;634 int err = 0;635 u8 out8_mux = 0;636 u8 out11_mux = 0;637 u8 temp;638 u16 output_mask = channel->output_mask;639 640 err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE,641 &temp, sizeof(temp));642 if (err)643 return err;644 645 if ((temp & Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK) ==646 Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK)647 out8_mux = 1;648 649 err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE,650 &temp, sizeof(temp));651 if (err)652 return err;653 654 if ((temp & Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK) ==655 Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK)656 out11_mux = 1;657 658 for (pll = 0; pll < 8; pll++) {659 qn = 0;660 qn_plus_1 = 0;661 662 if (pll < 4) {663 /* First 4 pll has 2 outputs */664 qn = output_mask & 0x1;665 output_mask = output_mask >> 1;666 qn_plus_1 = output_mask & 0x1;667 output_mask = output_mask >> 1;668 } else if (pll == 4) {669 if (out8_mux == 0) {670 qn = output_mask & 0x1;671 output_mask = output_mask >> 1;672 }673 } else if (pll == 5) {674 if (out8_mux) {675 qn_plus_1 = output_mask & 0x1;676 output_mask = output_mask >> 1;677 }678 qn = output_mask & 0x1;679 output_mask = output_mask >> 1;680 } else if (pll == 6) {681 qn = output_mask & 0x1;682 output_mask = output_mask >> 1;683 if (out11_mux) {684 qn_plus_1 = output_mask & 0x1;685 output_mask = output_mask >> 1;686 }687 } else if (pll == 7) {688 if (out11_mux == 0) {689 qn = output_mask & 0x1;690 output_mask = output_mask >> 1;691 }692 }693 694 if (qn != 0 || qn_plus_1 != 0)695 err = _sync_pll_output(idtcm, pll, channel->sync_src,696 qn, qn_plus_1);697 698 if (err)699 return err;700 }701 702 return err;703}704 705static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,706 struct timespec64 const *ts,707 enum hw_tod_write_trig_sel wr_trig)708{709 struct idtcm *idtcm = channel->idtcm;710 u8 buf[TOD_BYTE_COUNT];711 u8 cmd;712 int err;713 struct timespec64 local_ts = *ts;714 s64 total_overhead_ns;715 716 /* Configure HW TOD write trigger. */717 err = idtcm_read(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,718 &cmd, sizeof(cmd));719 if (err)720 return err;721 722 cmd &= ~(0x0f);723 cmd |= wr_trig | 0x08;724 725 err = idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,726 &cmd, sizeof(cmd));727 if (err)728 return err;729 730 if (wr_trig != HW_TOD_WR_TRIG_SEL_MSB) {731 err = timespec_to_char_array(&local_ts, buf, sizeof(buf));732 if (err)733 return err;734 735 err = idtcm_write(idtcm, channel->hw_dpll_n,736 HW_DPLL_TOD_OVR__0, buf, sizeof(buf));737 if (err)738 return err;739 }740 741 /* ARM HW TOD write trigger. */742 cmd &= ~(0x08);743 744 err = idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,745 &cmd, sizeof(cmd));746 747 if (wr_trig == HW_TOD_WR_TRIG_SEL_MSB) {748 if (idtcm->calculate_overhead_flag) {749 /* Assumption: I2C @ 400KHz */750 ktime_t diff = ktime_sub(ktime_get_raw(),751 idtcm->start_time);752 total_overhead_ns = ktime_to_ns(diff)753 + idtcm->tod_write_overhead_ns754 + SETTIME_CORRECTION;755 756 timespec64_add_ns(&local_ts, total_overhead_ns);757 758 idtcm->calculate_overhead_flag = 0;759 }760 761 err = timespec_to_char_array(&local_ts, buf, sizeof(buf));762 if (err)763 return err;764 765 err = idtcm_write(idtcm, channel->hw_dpll_n,766 HW_DPLL_TOD_OVR__0, buf, sizeof(buf));767 }768 769 return err;770}771 772static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel,773 struct timespec64 const *ts,774 enum scsr_tod_write_trig_sel wr_trig,775 enum scsr_tod_write_type_sel wr_type)776{777 struct idtcm *idtcm = channel->idtcm;778 unsigned char buf[TOD_BYTE_COUNT], cmd;779 struct timespec64 local_ts = *ts;780 int err, count = 0;781 782 timespec64_add_ns(&local_ts, SETTIME_CORRECTION);783 784 err = timespec_to_char_array(&local_ts, buf, sizeof(buf));785 if (err)786 return err;787 788 err = idtcm_write(idtcm, channel->tod_write, TOD_WRITE,789 buf, sizeof(buf));790 if (err)791 return err;792 793 /* Trigger the write operation. */794 err = idtcm_read(idtcm, channel->tod_write, TOD_WRITE_CMD,795 &cmd, sizeof(cmd));796 if (err)797 return err;798 799 cmd &= ~(TOD_WRITE_SELECTION_MASK << TOD_WRITE_SELECTION_SHIFT);800 cmd &= ~(TOD_WRITE_TYPE_MASK << TOD_WRITE_TYPE_SHIFT);801 cmd |= (wr_trig << TOD_WRITE_SELECTION_SHIFT);802 cmd |= (wr_type << TOD_WRITE_TYPE_SHIFT);803 804 err = idtcm_write(idtcm, channel->tod_write, TOD_WRITE_CMD,805 &cmd, sizeof(cmd));806 if (err)807 return err;808 809 /* Wait for the operation to complete. */810 while (1) {811 /* pps trigger takes up to 1 sec to complete */812 if (wr_trig == SCSR_TOD_WR_TRIG_SEL_TODPPS)813 msleep(50);814 815 err = idtcm_read(idtcm, channel->tod_write, TOD_WRITE_CMD,816 &cmd, sizeof(cmd));817 if (err)818 return err;819 820 if ((cmd & TOD_WRITE_SELECTION_MASK) == 0)821 break;822 823 if (++count > 20) {824 dev_err(idtcm->dev,825 "Timed out waiting for the write counter");826 return -EIO;827 }828 }829 830 return 0;831}832 833static int get_output_base_addr(enum fw_version ver, u8 outn)834{835 int base;836 837 switch (outn) {838 case 0:839 base = IDTCM_FW_REG(ver, V520, OUTPUT_0);840 break;841 case 1:842 base = IDTCM_FW_REG(ver, V520, OUTPUT_1);843 break;844 case 2:845 base = IDTCM_FW_REG(ver, V520, OUTPUT_2);846 break;847 case 3:848 base = IDTCM_FW_REG(ver, V520, OUTPUT_3);849 break;850 case 4:851 base = IDTCM_FW_REG(ver, V520, OUTPUT_4);852 break;853 case 5:854 base = IDTCM_FW_REG(ver, V520, OUTPUT_5);855 break;856 case 6:857 base = IDTCM_FW_REG(ver, V520, OUTPUT_6);858 break;859 case 7:860 base = IDTCM_FW_REG(ver, V520, OUTPUT_7);861 break;862 case 8:863 base = IDTCM_FW_REG(ver, V520, OUTPUT_8);864 break;865 case 9:866 base = IDTCM_FW_REG(ver, V520, OUTPUT_9);867 break;868 case 10:869 base = IDTCM_FW_REG(ver, V520, OUTPUT_10);870 break;871 case 11:872 base = IDTCM_FW_REG(ver, V520, OUTPUT_11);873 break;874 default:875 base = -EINVAL;876 }877 878 return base;879}880 881static int _idtcm_settime_deprecated(struct idtcm_channel *channel,882 struct timespec64 const *ts)883{884 struct idtcm *idtcm = channel->idtcm;885 int err;886 887 err = _idtcm_set_dpll_hw_tod(channel, ts, HW_TOD_WR_TRIG_SEL_MSB);888 if (err) {889 dev_err(idtcm->dev,890 "%s: Set HW ToD failed", __func__);891 return err;892 }893 894 return idtcm_sync_pps_output(channel);895}896 897static int _idtcm_settime(struct idtcm_channel *channel,898 struct timespec64 const *ts,899 enum scsr_tod_write_type_sel wr_type)900{901 return _idtcm_set_dpll_scsr_tod(channel, ts,902 SCSR_TOD_WR_TRIG_SEL_IMMEDIATE,903 wr_type);904}905 906static int idtcm_set_phase_pull_in_offset(struct idtcm_channel *channel,907 s32 offset_ns)908{909 int err;910 int i;911 struct idtcm *idtcm = channel->idtcm;912 u8 buf[4];913 914 for (i = 0; i < 4; i++) {915 buf[i] = 0xff & (offset_ns);916 offset_ns >>= 8;917 }918 919 err = idtcm_write(idtcm, channel->dpll_phase_pull_in, PULL_IN_OFFSET,920 buf, sizeof(buf));921 922 return err;923}924 925static int idtcm_set_phase_pull_in_slope_limit(struct idtcm_channel *channel,926 u32 max_ffo_ppb)927{928 int err;929 u8 i;930 struct idtcm *idtcm = channel->idtcm;931 u8 buf[3];932 933 if (max_ffo_ppb & 0xff000000)934 max_ffo_ppb = 0;935 936 for (i = 0; i < 3; i++) {937 buf[i] = 0xff & (max_ffo_ppb);938 max_ffo_ppb >>= 8;939 }940 941 err = idtcm_write(idtcm, channel->dpll_phase_pull_in,942 PULL_IN_SLOPE_LIMIT, buf, sizeof(buf));943 944 return err;945}946 947static int idtcm_start_phase_pull_in(struct idtcm_channel *channel)948{949 int err;950 struct idtcm *idtcm = channel->idtcm;951 u8 buf;952 953 err = idtcm_read(idtcm, channel->dpll_phase_pull_in, PULL_IN_CTRL,954 &buf, sizeof(buf));955 if (err)956 return err;957 958 if (buf == 0) {959 buf = 0x01;960 err = idtcm_write(idtcm, channel->dpll_phase_pull_in,961 PULL_IN_CTRL, &buf, sizeof(buf));962 } else {963 err = -EBUSY;964 }965 966 return err;967}968 969static int do_phase_pull_in_fw(struct idtcm_channel *channel,970 s32 offset_ns,971 u32 max_ffo_ppb)972{973 int err;974 975 err = idtcm_set_phase_pull_in_offset(channel, -offset_ns);976 if (err)977 return err;978 979 err = idtcm_set_phase_pull_in_slope_limit(channel, max_ffo_ppb);980 if (err)981 return err;982 983 err = idtcm_start_phase_pull_in(channel);984 985 return err;986}987 988static int set_tod_write_overhead(struct idtcm_channel *channel)989{990 struct idtcm *idtcm = channel->idtcm;991 s64 current_ns = 0;992 s64 lowest_ns = 0;993 int err;994 u8 i;995 ktime_t start;996 ktime_t stop;997 ktime_t diff;998 999 char buf[TOD_BYTE_COUNT] = {0};1000 1001 /* Set page offset */1002 idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_OVR__0,1003 buf, sizeof(buf));1004 1005 for (i = 0; i < TOD_WRITE_OVERHEAD_COUNT_MAX; i++) {1006 start = ktime_get_raw();1007 1008 err = idtcm_write(idtcm, channel->hw_dpll_n,1009 HW_DPLL_TOD_OVR__0, buf, sizeof(buf));1010 if (err)1011 return err;1012 1013 stop = ktime_get_raw();1014 1015 diff = ktime_sub(stop, start);1016 1017 current_ns = ktime_to_ns(diff);1018 1019 if (i == 0) {1020 lowest_ns = current_ns;1021 } else {1022 if (current_ns < lowest_ns)1023 lowest_ns = current_ns;1024 }1025 }1026 1027 idtcm->tod_write_overhead_ns = lowest_ns;1028 1029 return err;1030}1031 1032static int _idtcm_adjtime_deprecated(struct idtcm_channel *channel, s64 delta)1033{1034 int err;1035 struct idtcm *idtcm = channel->idtcm;1036 struct timespec64 ts;1037 s64 now;1038 1039 if (abs(delta) < PHASE_PULL_IN_THRESHOLD_NS_DEPRECATED) {1040 err = channel->do_phase_pull_in(channel, delta, 0);1041 } else {1042 idtcm->calculate_overhead_flag = 1;1043 1044 err = set_tod_write_overhead(channel);1045 if (err)1046 return err;1047 1048 err = _idtcm_gettime_immediate(channel, &ts);1049 if (err)1050 return err;1051 1052 now = timespec64_to_ns(&ts);1053 now += delta;1054 1055 ts = ns_to_timespec64(now);1056 1057 err = _idtcm_settime_deprecated(channel, &ts);1058 }1059 1060 return err;1061}1062 1063static int idtcm_state_machine_reset(struct idtcm *idtcm)1064{1065 u8 byte = SM_RESET_CMD;1066 u32 status = 0;1067 int err;1068 u8 i;1069 1070 clear_boot_status(idtcm);1071 1072 err = idtcm_write(idtcm, RESET_CTRL,1073 IDTCM_FW_REG(idtcm->fw_ver, V520, SM_RESET),1074 &byte, sizeof(byte));1075 1076 if (!err) {1077 for (i = 0; i < 30; i++) {1078 msleep_interruptible(100);1079 read_boot_status(idtcm, &status);1080 1081 if (status == 0xA0) {1082 dev_dbg(idtcm->dev,1083 "SM_RESET completed in %d ms", i * 100);1084 break;1085 }1086 }1087 1088 if (!status)1089 dev_err(idtcm->dev,1090 "Timed out waiting for CM_RESET to complete");1091 }1092 1093 return err;1094}1095 1096static int idtcm_read_hw_rev_id(struct idtcm *idtcm, u8 *hw_rev_id)1097{1098 return idtcm_read(idtcm, HW_REVISION, REV_ID, hw_rev_id, sizeof(u8));1099}1100 1101static int idtcm_read_product_id(struct idtcm *idtcm, u16 *product_id)1102{1103 int err;1104 u8 buf[2] = {0};1105 1106 err = idtcm_read(idtcm, GENERAL_STATUS, PRODUCT_ID, buf, sizeof(buf));1107 1108 *product_id = (buf[1] << 8) | buf[0];1109 1110 return err;1111}1112 1113static int idtcm_read_major_release(struct idtcm *idtcm, u8 *major)1114{1115 int err;1116 u8 buf = 0;1117 1118 err = idtcm_read(idtcm, GENERAL_STATUS, MAJ_REL, &buf, sizeof(buf));1119 1120 *major = buf >> 1;1121 1122 return err;1123}1124 1125static int idtcm_read_minor_release(struct idtcm *idtcm, u8 *minor)1126{1127 return idtcm_read(idtcm, GENERAL_STATUS, MIN_REL, minor, sizeof(u8));1128}1129 1130static int idtcm_read_hotfix_release(struct idtcm *idtcm, u8 *hotfix)1131{1132 return idtcm_read(idtcm,1133 GENERAL_STATUS,1134 HOTFIX_REL,1135 hotfix,1136 sizeof(u8));1137}1138 1139static int idtcm_read_otp_scsr_config_select(struct idtcm *idtcm,1140 u8 *config_select)1141{1142 return idtcm_read(idtcm, GENERAL_STATUS, OTP_SCSR_CONFIG_SELECT,1143 config_select, sizeof(u8));1144}1145 1146static int set_pll_output_mask(struct idtcm *idtcm, u16 addr, u8 val)1147{1148 int err = 0;1149 1150 switch (addr) {1151 case TOD0_OUT_ALIGN_MASK_ADDR:1152 SET_U16_LSB(idtcm->channel[0].output_mask, val);1153 break;1154 case TOD0_OUT_ALIGN_MASK_ADDR + 1:1155 SET_U16_MSB(idtcm->channel[0].output_mask, val);1156 break;1157 case TOD1_OUT_ALIGN_MASK_ADDR:1158 SET_U16_LSB(idtcm->channel[1].output_mask, val);1159 break;1160 case TOD1_OUT_ALIGN_MASK_ADDR + 1:1161 SET_U16_MSB(idtcm->channel[1].output_mask, val);1162 break;1163 case TOD2_OUT_ALIGN_MASK_ADDR:1164 SET_U16_LSB(idtcm->channel[2].output_mask, val);1165 break;1166 case TOD2_OUT_ALIGN_MASK_ADDR + 1:1167 SET_U16_MSB(idtcm->channel[2].output_mask, val);1168 break;1169 case TOD3_OUT_ALIGN_MASK_ADDR:1170 SET_U16_LSB(idtcm->channel[3].output_mask, val);1171 break;1172 case TOD3_OUT_ALIGN_MASK_ADDR + 1:1173 SET_U16_MSB(idtcm->channel[3].output_mask, val);1174 break;1175 default:1176 err = -EFAULT; /* Bad address */;1177 break;1178 }1179 1180 return err;1181}1182 1183static int set_tod_ptp_pll(struct idtcm *idtcm, u8 index, u8 pll)1184{1185 if (index >= MAX_TOD) {1186 dev_err(idtcm->dev, "ToD%d not supported", index);1187 return -EINVAL;1188 }1189 1190 if (pll >= MAX_PLL) {1191 dev_err(idtcm->dev, "Pll%d not supported", pll);1192 return -EINVAL;1193 }1194 1195 idtcm->channel[index].pll = pll;1196 1197 return 0;1198}1199 1200static int check_and_set_masks(struct idtcm *idtcm,1201 u16 regaddr,1202 u8 val)1203{1204 int err = 0;1205 1206 switch (regaddr) {1207 case TOD_MASK_ADDR:1208 if ((val & 0xf0) || !(val & 0x0f)) {1209 dev_err(idtcm->dev, "Invalid TOD mask 0x%02x", val);1210 err = -EINVAL;1211 } else {1212 idtcm->tod_mask = val;1213 }1214 break;1215 case TOD0_PTP_PLL_ADDR:1216 err = set_tod_ptp_pll(idtcm, 0, val);1217 break;1218 case TOD1_PTP_PLL_ADDR:1219 err = set_tod_ptp_pll(idtcm, 1, val);1220 break;1221 case TOD2_PTP_PLL_ADDR:1222 err = set_tod_ptp_pll(idtcm, 2, val);1223 break;1224 case TOD3_PTP_PLL_ADDR:1225 err = set_tod_ptp_pll(idtcm, 3, val);1226 break;1227 default:1228 err = set_pll_output_mask(idtcm, regaddr, val);1229 break;1230 }1231 1232 return err;1233}1234 1235static void display_pll_and_masks(struct idtcm *idtcm)1236{1237 u8 i;1238 u8 mask;1239 1240 dev_dbg(idtcm->dev, "tod_mask = 0x%02x", idtcm->tod_mask);1241 1242 for (i = 0; i < MAX_TOD; i++) {1243 mask = 1 << i;1244 1245 if (mask & idtcm->tod_mask)1246 dev_dbg(idtcm->dev,1247 "TOD%d pll = %d output_mask = 0x%04x",1248 i, idtcm->channel[i].pll,1249 idtcm->channel[i].output_mask);1250 }1251}1252 1253static int idtcm_load_firmware(struct idtcm *idtcm,1254 struct device *dev)1255{1256 u16 scratch = IDTCM_FW_REG(idtcm->fw_ver, V520, SCRATCH);1257 char fname[128] = FW_FILENAME;1258 const struct firmware *fw;1259 struct idtcm_fwrc *rec;1260 u32 regaddr;1261 int err;1262 s32 len;1263 u8 val;1264 u8 loaddr;1265 1266 if (firmware) /* module parameter */1267 snprintf(fname, sizeof(fname), "%s", firmware);1268 1269 dev_info(idtcm->dev, "requesting firmware '%s'", fname);1270 1271 err = request_firmware(&fw, fname, dev);1272 if (err) {1273 dev_err(idtcm->dev,1274 "Failed at line %d in %s!", __LINE__, __func__);1275 return err;1276 }1277 1278 dev_dbg(idtcm->dev, "firmware size %zu bytes", fw->size);1279 1280 rec = (struct idtcm_fwrc *) fw->data;1281 1282 if (contains_full_configuration(idtcm, fw))1283 idtcm_state_machine_reset(idtcm);1284 1285 for (len = fw->size; len > 0; len -= sizeof(*rec)) {1286 if (rec->reserved) {1287 dev_err(idtcm->dev,1288 "bad firmware, reserved field non-zero");1289 err = -EINVAL;1290 } else {1291 regaddr = rec->hiaddr << 8;1292 regaddr |= rec->loaddr;1293 1294 val = rec->value;1295 loaddr = rec->loaddr;1296 1297 rec++;1298 1299 err = check_and_set_masks(idtcm, regaddr, val);1300 }1301 1302 if (err != -EINVAL) {1303 err = 0;1304 1305 /* Top (status registers) and bottom are read-only */1306 if (regaddr < GPIO_USER_CONTROL || regaddr >= scratch)1307 continue;1308 1309 /* Page size 128, last 4 bytes of page skipped */1310 if ((loaddr > 0x7b && loaddr <= 0x7f) || loaddr > 0xfb)1311 continue;1312 1313 err = idtcm_write(idtcm, regaddr, 0, &val, sizeof(val));1314 }1315 1316 if (err)1317 goto out;1318 }1319 1320 display_pll_and_masks(idtcm);1321 1322out:1323 release_firmware(fw);1324 return err;1325}1326 1327static int idtcm_output_enable(struct idtcm_channel *channel,1328 bool enable, unsigned int outn)1329{1330 struct idtcm *idtcm = channel->idtcm;1331 int base;1332 int err;1333 u8 val;1334 1335 base = get_output_base_addr(idtcm->fw_ver, outn);1336 1337 if (!(base > 0)) {1338 dev_err(idtcm->dev,1339 "%s - Unsupported out%d", __func__, outn);1340 return base;1341 }1342 1343 err = idtcm_read(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val));1344 if (err)1345 return err;1346 1347 if (enable)1348 val |= SQUELCH_DISABLE;1349 else1350 val &= ~SQUELCH_DISABLE;1351 1352 return idtcm_write(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val));1353}1354 1355static int idtcm_perout_enable(struct idtcm_channel *channel,1356 struct ptp_perout_request *perout,1357 bool enable)1358{1359 struct idtcm *idtcm = channel->idtcm;1360 struct timespec64 ts = {0, 0};1361 int err;1362 1363 err = idtcm_output_enable(channel, enable, perout->index);1364 1365 if (err) {1366 dev_err(idtcm->dev, "Unable to set output enable");1367 return err;1368 }1369 1370 /* Align output to internal 1 PPS */1371 return _idtcm_settime(channel, &ts, SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS);1372}1373 1374static int idtcm_get_pll_mode(struct idtcm_channel *channel,1375 enum pll_mode *mode)1376{1377 struct idtcm *idtcm = channel->idtcm;1378 int err;1379 u8 dpll_mode;1380 1381 err = idtcm_read(idtcm, channel->dpll_n,1382 IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_MODE),1383 &dpll_mode, sizeof(dpll_mode));1384 if (err)1385 return err;1386 1387 *mode = (dpll_mode >> PLL_MODE_SHIFT) & PLL_MODE_MASK;1388 1389 return 0;1390}1391 1392static int idtcm_set_pll_mode(struct idtcm_channel *channel,1393 enum pll_mode mode)1394{1395 struct idtcm *idtcm = channel->idtcm;1396 int err;1397 u8 dpll_mode;1398 1399 err = idtcm_read(idtcm, channel->dpll_n,1400 IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_MODE),1401 &dpll_mode, sizeof(dpll_mode));1402 if (err)1403 return err;1404 1405 dpll_mode &= ~(PLL_MODE_MASK << PLL_MODE_SHIFT);1406 1407 dpll_mode |= (mode << PLL_MODE_SHIFT);1408 1409 err = idtcm_write(idtcm, channel->dpll_n,1410 IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_MODE),1411 &dpll_mode, sizeof(dpll_mode));1412 return err;1413}1414 1415static int idtcm_get_manual_reference(struct idtcm_channel *channel,1416 enum manual_reference *ref)1417{1418 struct idtcm *idtcm = channel->idtcm;1419 u8 dpll_manu_ref_cfg;1420 int err;1421 1422 err = idtcm_read(idtcm, channel->dpll_ctrl_n,1423 DPLL_CTRL_DPLL_MANU_REF_CFG,1424 &dpll_manu_ref_cfg, sizeof(dpll_manu_ref_cfg));1425 if (err)1426 return err;1427 1428 dpll_manu_ref_cfg &= (MANUAL_REFERENCE_MASK << MANUAL_REFERENCE_SHIFT);1429 1430 *ref = dpll_manu_ref_cfg >> MANUAL_REFERENCE_SHIFT;1431 1432 return 0;1433}1434 1435static int idtcm_set_manual_reference(struct idtcm_channel *channel,1436 enum manual_reference ref)1437{1438 struct idtcm *idtcm = channel->idtcm;1439 u8 dpll_manu_ref_cfg;1440 int err;1441 1442 err = idtcm_read(idtcm, channel->dpll_ctrl_n,1443 DPLL_CTRL_DPLL_MANU_REF_CFG,1444 &dpll_manu_ref_cfg, sizeof(dpll_manu_ref_cfg));1445 if (err)1446 return err;1447 1448 dpll_manu_ref_cfg &= ~(MANUAL_REFERENCE_MASK << MANUAL_REFERENCE_SHIFT);1449 1450 dpll_manu_ref_cfg |= (ref << MANUAL_REFERENCE_SHIFT);1451 1452 err = idtcm_write(idtcm, channel->dpll_ctrl_n,1453 DPLL_CTRL_DPLL_MANU_REF_CFG,1454 &dpll_manu_ref_cfg, sizeof(dpll_manu_ref_cfg));1455 1456 return err;1457}1458 1459static int configure_dpll_mode_write_frequency(struct idtcm_channel *channel)1460{1461 struct idtcm *idtcm = channel->idtcm;1462 int err;1463 1464 err = idtcm_set_pll_mode(channel, PLL_MODE_WRITE_FREQUENCY);1465 1466 if (err)1467 dev_err(idtcm->dev, "Failed to set pll mode to write frequency");1468 else1469 channel->mode = PTP_PLL_MODE_WRITE_FREQUENCY;1470 1471 return err;1472}1473 1474static int configure_dpll_mode_write_phase(struct idtcm_channel *channel)1475{1476 struct idtcm *idtcm = channel->idtcm;1477 int err;1478 1479 err = idtcm_set_pll_mode(channel, PLL_MODE_WRITE_PHASE);1480 1481 if (err)1482 dev_err(idtcm->dev, "Failed to set pll mode to write phase");1483 else1484 channel->mode = PTP_PLL_MODE_WRITE_PHASE;1485 1486 return err;1487}1488 1489static int configure_manual_reference_write_frequency(struct idtcm_channel *channel)1490{1491 struct idtcm *idtcm = channel->idtcm;1492 int err;1493 1494 err = idtcm_set_manual_reference(channel, MANU_REF_WRITE_FREQUENCY);1495 1496 if (err)1497 dev_err(idtcm->dev, "Failed to set manual reference to write frequency");1498 else1499 channel->mode = PTP_PLL_MODE_WRITE_FREQUENCY;1500 1501 return err;1502}1503 1504static int configure_manual_reference_write_phase(struct idtcm_channel *channel)1505{1506 struct idtcm *idtcm = channel->idtcm;1507 int err;1508 1509 err = idtcm_set_manual_reference(channel, MANU_REF_WRITE_PHASE);1510 1511 if (err)1512 dev_err(idtcm->dev, "Failed to set manual reference to write phase");1513 else1514 channel->mode = PTP_PLL_MODE_WRITE_PHASE;1515 1516 return err;1517}1518 1519static int idtcm_stop_phase_pull_in(struct idtcm_channel *channel)1520{1521 int err;1522 1523 err = _idtcm_adjfine(channel, channel->current_freq_scaled_ppm);1524 if (err)1525 return err;1526 1527 channel->phase_pull_in = false;1528 1529 return 0;1530}1531 1532static long idtcm_work_handler(struct ptp_clock_info *ptp)1533{1534 struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);1535 struct idtcm *idtcm = channel->idtcm;1536 1537 mutex_lock(idtcm->lock);1538 1539 (void)idtcm_stop_phase_pull_in(channel);1540 1541 mutex_unlock(idtcm->lock);1542 1543 /* Return a negative value here to not reschedule */1544 return -1;1545}1546 1547static s32 phase_pull_in_scaled_ppm(s32 current_ppm, s32 phase_pull_in_ppb)1548{1549 /* ppb = scaled_ppm * 125 / 2^13 */1550 /* scaled_ppm = ppb * 2^13 / 125 */1551 1552 s64 max_scaled_ppm = div_s64((s64)PHASE_PULL_IN_MAX_PPB << 13, 125);1553 s64 scaled_ppm = div_s64((s64)phase_pull_in_ppb << 13, 125);1554 1555 current_ppm += scaled_ppm;1556 1557 if (current_ppm > max_scaled_ppm)1558 current_ppm = max_scaled_ppm;1559 else if (current_ppm < -max_scaled_ppm)1560 current_ppm = -max_scaled_ppm;1561 1562 return current_ppm;1563}1564 1565static int do_phase_pull_in_sw(struct idtcm_channel *channel,1566 s32 delta_ns,1567 u32 max_ffo_ppb)1568{1569 s32 current_ppm = channel->current_freq_scaled_ppm;1570 u32 duration_ms = MSEC_PER_SEC;1571 s32 delta_ppm;1572 s32 ppb;1573 int err;1574 1575 /* If the ToD correction is less than PHASE_PULL_IN_MIN_THRESHOLD_NS,1576 * skip. The error introduced by the ToD adjustment procedure would1577 * be bigger than the required ToD correction1578 */1579 if (abs(delta_ns) < PHASE_PULL_IN_MIN_THRESHOLD_NS)1580 return 0;1581 1582 if (max_ffo_ppb == 0)1583 max_ffo_ppb = PHASE_PULL_IN_MAX_PPB;1584 1585 /* For most cases, keep phase pull-in duration 1 second */1586 ppb = delta_ns;1587 while (abs(ppb) > max_ffo_ppb) {1588 duration_ms *= 2;1589 ppb /= 2;1590 }1591 1592 delta_ppm = phase_pull_in_scaled_ppm(current_ppm, ppb);1593 1594 err = _idtcm_adjfine(channel, delta_ppm);1595 1596 if (err)1597 return err;1598 1599 /* schedule the worker to cancel phase pull-in */1600 ptp_schedule_worker(channel->ptp_clock,1601 msecs_to_jiffies(duration_ms) - 1);1602 1603 channel->phase_pull_in = true;1604 1605 return 0;1606}1607 1608static int initialize_operating_mode_with_manual_reference(struct idtcm_channel *channel,1609 enum manual_reference ref)1610{1611 struct idtcm *idtcm = channel->idtcm;1612 1613 channel->mode = PTP_PLL_MODE_UNSUPPORTED;1614 channel->configure_write_frequency = configure_manual_reference_write_frequency;1615 channel->configure_write_phase = configure_manual_reference_write_phase;1616 channel->do_phase_pull_in = do_phase_pull_in_sw;1617 1618 switch (ref) {1619 case MANU_REF_WRITE_PHASE:1620 channel->mode = PTP_PLL_MODE_WRITE_PHASE;1621 break;1622 case MANU_REF_WRITE_FREQUENCY:1623 channel->mode = PTP_PLL_MODE_WRITE_FREQUENCY;1624 break;1625 default:1626 dev_warn(idtcm->dev,1627 "Unsupported MANUAL_REFERENCE: 0x%02x", ref);1628 }1629 1630 return 0;1631}1632 1633static int initialize_operating_mode_with_pll_mode(struct idtcm_channel *channel,1634 enum pll_mode mode)1635{1636 struct idtcm *idtcm = channel->idtcm;1637 int err = 0;1638 1639 channel->mode = PTP_PLL_MODE_UNSUPPORTED;1640 channel->configure_write_frequency = configure_dpll_mode_write_frequency;1641 channel->configure_write_phase = configure_dpll_mode_write_phase;1642 channel->do_phase_pull_in = do_phase_pull_in_fw;1643 1644 switch (mode) {1645 case PLL_MODE_WRITE_PHASE:1646 channel->mode = PTP_PLL_MODE_WRITE_PHASE;1647 break;1648 case PLL_MODE_WRITE_FREQUENCY:1649 channel->mode = PTP_PLL_MODE_WRITE_FREQUENCY;1650 break;1651 default:1652 dev_err(idtcm->dev,1653 "Unsupported PLL_MODE: 0x%02x", mode);1654 err = -EINVAL;1655 }1656 1657 return err;1658}1659 1660static int initialize_dco_operating_mode(struct idtcm_channel *channel)1661{1662 enum manual_reference ref = MANU_REF_XO_DPLL;1663 enum pll_mode mode = PLL_MODE_DISABLED;1664 struct idtcm *idtcm = channel->idtcm;1665 int err;1666 1667 channel->mode = PTP_PLL_MODE_UNSUPPORTED;1668 1669 err = idtcm_get_pll_mode(channel, &mode);1670 if (err) {1671 dev_err(idtcm->dev, "Unable to read pll mode!");1672 return err;1673 }1674 1675 if (mode == PLL_MODE_PLL) {1676 err = idtcm_get_manual_reference(channel, &ref);1677 if (err) {1678 dev_err(idtcm->dev, "Unable to read manual reference!");1679 return err;1680 }1681 err = initialize_operating_mode_with_manual_reference(channel, ref);1682 } else {1683 err = initialize_operating_mode_with_pll_mode(channel, mode);1684 }1685 1686 if (channel->mode == PTP_PLL_MODE_WRITE_PHASE)1687 channel->configure_write_frequency(channel);1688 1689 return err;1690}1691 1692/* PTP Hardware Clock interface */1693 1694/*1695 * Maximum absolute value for write phase offset in nanoseconds1696 *1697 * Destination signed register is 32-bit register in resolution of 50ps1698 *1699 * 0x7fffffff * 50 = 2147483647 * 50 = 107374182350 ps1700 * Represent 107374182350 ps as 107374182 ns1701 */1702static s32 idtcm_getmaxphase(struct ptp_clock_info *ptp __always_unused)1703{1704 return MAX_ABS_WRITE_PHASE_NANOSECONDS;1705}1706 1707/*1708 * Internal function for implementing support for write phase offset1709 *1710 * @channel: channel1711 * @delta_ns: delta in nanoseconds1712 */1713static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)1714{1715 struct idtcm *idtcm = channel->idtcm;1716 int err;1717 u8 i;1718 u8 buf[4] = {0};1719 s32 phase_50ps;1720 1721 if (channel->mode != PTP_PLL_MODE_WRITE_PHASE) {1722 err = channel->configure_write_phase(channel);1723 if (err)1724 return err;1725 }1726 1727 phase_50ps = div_s64((s64)delta_ns * 1000, 50);1728 1729 for (i = 0; i < 4; i++) {1730 buf[i] = phase_50ps & 0xff;1731 phase_50ps >>= 8;1732 }1733 1734 err = idtcm_write(idtcm, channel->dpll_phase, DPLL_WR_PHASE,1735 buf, sizeof(buf));1736 1737 return err;1738}1739 1740static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm)1741{1742 struct idtcm *idtcm = channel->idtcm;1743 u8 i;1744 int err;1745 u8 buf[6] = {0};1746 s64 fcw;1747 1748 if (channel->mode != PTP_PLL_MODE_WRITE_FREQUENCY) {1749 err = channel->configure_write_frequency(channel);1750 if (err)1751 return err;1752 }1753 1754 /*1755 * Frequency Control Word unit is: 1.11 * 10^-10 ppm1756 *1757 * adjfreq:1758 * ppb * 10^91759 * FCW = ----------1760 * 1111761 *1762 * adjfine:1763 * ppm_16 * 5^121764 * FCW = -------------1765 * 111 * 2^41766 */1767 1768 /* 2 ^ -53 = 1.1102230246251565404236316680908e-16 */1769 fcw = scaled_ppm * 244140625ULL;1770 1771 fcw = div_s64(fcw, 1776);1772 1773 for (i = 0; i < 6; i++) {1774 buf[i] = fcw & 0xff;1775 fcw >>= 8;1776 }1777 1778 err = idtcm_write(idtcm, channel->dpll_freq, DPLL_WR_FREQ,1779 buf, sizeof(buf));1780 1781 return err;1782}1783 1784static int idtcm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)1785{1786 struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);1787 struct idtcm *idtcm = channel->idtcm;1788 int err;1789 1790 mutex_lock(idtcm->lock);1791 err = _idtcm_gettime_immediate(channel, ts);1792 mutex_unlock(idtcm->lock);1793 1794 if (err)1795 dev_err(idtcm->dev, "Failed at line %d in %s!",1796 __LINE__, __func__);1797 1798 return err;1799}1800 1801static int idtcm_settime_deprecated(struct ptp_clock_info *ptp,1802 const struct timespec64 *ts)1803{1804 struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);1805 struct idtcm *idtcm = channel->idtcm;1806 int err;1807 1808 mutex_lock(idtcm->lock);1809 err = _idtcm_settime_deprecated(channel, ts);1810 mutex_unlock(idtcm->lock);1811 1812 if (err)1813 dev_err(idtcm->dev,1814 "Failed at line %d in %s!", __LINE__, __func__);1815 1816 return err;1817}1818 1819static int idtcm_settime(struct ptp_clock_info *ptp,1820 const struct timespec64 *ts)1821{1822 struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);1823 struct idtcm *idtcm = channel->idtcm;1824 int err;1825 1826 mutex_lock(idtcm->lock);1827 err = _idtcm_settime(channel, ts, SCSR_TOD_WR_TYPE_SEL_ABSOLUTE);1828 mutex_unlock(idtcm->lock);1829 1830 if (err)1831 dev_err(idtcm->dev,1832 "Failed at line %d in %s!", __LINE__, __func__);1833 1834 return err;1835}1836 1837static int idtcm_adjtime_deprecated(struct ptp_clock_info *ptp, s64 delta)1838{1839 struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);1840 struct idtcm *idtcm = channel->idtcm;1841 int err;1842 1843 mutex_lock(idtcm->lock);1844 err = _idtcm_adjtime_deprecated(channel, delta);1845 mutex_unlock(idtcm->lock);1846 1847 if (err)1848 dev_err(idtcm->dev,1849 "Failed at line %d in %s!", __LINE__, __func__);1850 1851 return err;1852}1853 1854static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)1855{1856 struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);1857 struct idtcm *idtcm = channel->idtcm;1858 struct timespec64 ts;1859 enum scsr_tod_write_type_sel type;1860 int err;1861 1862 if (channel->phase_pull_in == true)1863 return -EBUSY;1864 1865 mutex_lock(idtcm->lock);1866 1867 if (abs(delta) < PHASE_PULL_IN_THRESHOLD_NS) {1868 err = channel->do_phase_pull_in(channel, delta, 0);1869 } else {1870 if (delta >= 0) {1871 ts = ns_to_timespec64(delta);1872 type = SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS;1873 } else {1874 ts = ns_to_timespec64(-delta);1875 type = SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS;1876 }1877 err = _idtcm_settime(channel, &ts, type);1878 }1879 1880 mutex_unlock(idtcm->lock);1881 1882 if (err)1883 dev_err(idtcm->dev,1884 "Failed at line %d in %s!", __LINE__, __func__);1885 1886 return err;1887}1888 1889static int idtcm_adjphase(struct ptp_clock_info *ptp, s32 delta)1890{1891 struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);1892 struct idtcm *idtcm = channel->idtcm;1893 int err;1894 1895 mutex_lock(idtcm->lock);1896 err = _idtcm_adjphase(channel, delta);1897 mutex_unlock(idtcm->lock);1898 1899 if (err)1900 dev_err(idtcm->dev,1901 "Failed at line %d in %s!", __LINE__, __func__);1902 1903 return err;1904}1905 1906static int idtcm_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)1907{1908 struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);1909 struct idtcm *idtcm = channel->idtcm;1910 int err;1911 1912 if (channel->phase_pull_in == true)1913 return 0;1914 1915 if (scaled_ppm == channel->current_freq_scaled_ppm)1916 return 0;1917 1918 mutex_lock(idtcm->lock);1919 err = _idtcm_adjfine(channel, scaled_ppm);1920 mutex_unlock(idtcm->lock);1921 1922 if (err)1923 dev_err(idtcm->dev,1924 "Failed at line %d in %s!", __LINE__, __func__);1925 else1926 channel->current_freq_scaled_ppm = scaled_ppm;1927 1928 return err;1929}1930 1931static int idtcm_enable(struct ptp_clock_info *ptp,1932 struct ptp_clock_request *rq, int on)1933{1934 struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);1935 struct idtcm *idtcm = channel->idtcm;1936 int err = -EOPNOTSUPP;1937 1938 mutex_lock(idtcm->lock);1939 1940 switch (rq->type) {1941 case PTP_CLK_REQ_PEROUT:1942 if (!on)1943 err = idtcm_perout_enable(channel, &rq->perout, false);1944 /* Only accept a 1-PPS aligned to the second. */1945 else if (rq->perout.start.nsec || rq->perout.period.sec != 1 ||1946 rq->perout.period.nsec)1947 err = -ERANGE;1948 else1949 err = idtcm_perout_enable(channel, &rq->perout, true);1950 break;1951 case PTP_CLK_REQ_EXTTS:1952 err = idtcm_extts_enable(channel, rq, on);1953 break;1954 default:1955 break;1956 }1957 1958 mutex_unlock(idtcm->lock);1959 1960 if (err)1961 dev_err(channel->idtcm->dev,1962 "Failed in %s with err %d!", __func__, err);1963 1964 return err;1965}1966 1967static int idtcm_enable_tod(struct idtcm_channel *channel)1968{1969 struct idtcm *idtcm = channel->idtcm;1970 struct timespec64 ts = {0, 0};1971 u16 tod_cfg = IDTCM_FW_REG(idtcm->fw_ver, V520, TOD_CFG);1972 u8 cfg;1973 int err;1974 1975 /*1976 * Start the TOD clock ticking.1977 */1978 err = idtcm_read(idtcm, channel->tod_n, tod_cfg, &cfg, sizeof(cfg));1979 if (err)1980 return err;1981 1982 cfg |= TOD_ENABLE;1983 1984 err = idtcm_write(idtcm, channel->tod_n, tod_cfg, &cfg, sizeof(cfg));1985 if (err)1986 return err;1987 1988 if (idtcm->fw_ver < V487)1989 return _idtcm_settime_deprecated(channel, &ts);1990 else1991 return _idtcm_settime(channel, &ts,1992 SCSR_TOD_WR_TYPE_SEL_ABSOLUTE);1993}1994 1995static void idtcm_set_version_info(struct idtcm *idtcm)1996{1997 u8 major;1998 u8 minor;1999 u8 hotfix;2000 u16 product_id;2001 u8 hw_rev_id;2002 u8 config_select;2003 2004 idtcm_read_major_release(idtcm, &major);2005 idtcm_read_minor_release(idtcm, &minor);2006 idtcm_read_hotfix_release(idtcm, &hotfix);2007 2008 idtcm_read_product_id(idtcm, &product_id);2009 idtcm_read_hw_rev_id(idtcm, &hw_rev_id);2010 2011 idtcm_read_otp_scsr_config_select(idtcm, &config_select);2012 2013 snprintf(idtcm->version, sizeof(idtcm->version), "%u.%u.%u",2014 major, minor, hotfix);2015 2016 idtcm->fw_ver = idtcm_fw_version(idtcm->version);2017 2018 dev_info(idtcm->dev,2019 "%d.%d.%d, Id: 0x%04x HW Rev: %d OTP Config Select: %d",2020 major, minor, hotfix,2021 product_id, hw_rev_id, config_select);2022}2023 2024static int idtcm_verify_pin(struct ptp_clock_info *ptp, unsigned int pin,2025 enum ptp_pin_function func, unsigned int chan)2026{2027 switch (func) {2028 case PTP_PF_NONE:2029 case PTP_PF_EXTTS:2030 break;2031 case PTP_PF_PEROUT:2032 case PTP_PF_PHYSYNC:2033 return -1;2034 }2035 return 0;2036}2037 2038static struct ptp_pin_desc pin_config[MAX_TOD][MAX_REF_CLK];2039 2040static const struct ptp_clock_info idtcm_caps = {2041 .owner = THIS_MODULE,2042 .max_adj = 244000,2043 .n_per_out = 12,2044 .n_ext_ts = MAX_TOD,2045 .n_pins = MAX_REF_CLK,2046 .adjphase = &idtcm_adjphase,2047 .getmaxphase = &idtcm_getmaxphase,2048 .adjfine = &idtcm_adjfine,2049 .adjtime = &idtcm_adjtime,2050 .gettime64 = &idtcm_gettime,2051 .settime64 = &idtcm_settime,2052 .enable = &idtcm_enable,2053 .verify = &idtcm_verify_pin,2054 .do_aux_work = &idtcm_work_handler,2055};2056 2057static const struct ptp_clock_info idtcm_caps_deprecated = {2058 .owner = THIS_MODULE,2059 .max_adj = 244000,2060 .n_per_out = 12,2061 .n_ext_ts = MAX_TOD,2062 .n_pins = MAX_REF_CLK,2063 .adjphase = &idtcm_adjphase,2064 .getmaxphase = &idtcm_getmaxphase,2065 .adjfine = &idtcm_adjfine,2066 .adjtime = &idtcm_adjtime_deprecated,2067 .gettime64 = &idtcm_gettime,2068 .settime64 = &idtcm_settime_deprecated,2069 .enable = &idtcm_enable,2070 .verify = &idtcm_verify_pin,2071 .do_aux_work = &idtcm_work_handler,2072};2073 2074static int configure_channel_pll(struct idtcm_channel *channel)2075{2076 struct idtcm *idtcm = channel->idtcm;2077 int err = 0;2078 2079 switch (channel->pll) {2080 case 0:2081 channel->dpll_freq = DPLL_FREQ_0;2082 channel->dpll_n = DPLL_0;2083 channel->hw_dpll_n = HW_DPLL_0;2084 channel->dpll_phase = DPLL_PHASE_0;2085 channel->dpll_ctrl_n = DPLL_CTRL_0;2086 channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_0;2087 break;2088 case 1:2089 channel->dpll_freq = DPLL_FREQ_1;2090 channel->dpll_n = DPLL_1;2091 channel->hw_dpll_n = HW_DPLL_1;2092 channel->dpll_phase = DPLL_PHASE_1;2093 channel->dpll_ctrl_n = DPLL_CTRL_1;2094 channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_1;2095 break;2096 case 2:2097 channel->dpll_freq = DPLL_FREQ_2;2098 channel->dpll_n = IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_2);2099 channel->hw_dpll_n = HW_DPLL_2;2100 channel->dpll_phase = DPLL_PHASE_2;2101 channel->dpll_ctrl_n = DPLL_CTRL_2;2102 channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_2;2103 break;2104 case 3:2105 channel->dpll_freq = DPLL_FREQ_3;2106 channel->dpll_n = DPLL_3;2107 channel->hw_dpll_n = HW_DPLL_3;2108 channel->dpll_phase = DPLL_PHASE_3;2109 channel->dpll_ctrl_n = DPLL_CTRL_3;2110 channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_3;2111 break;2112 case 4:2113 channel->dpll_freq = DPLL_FREQ_4;2114 channel->dpll_n = IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_4);2115 channel->hw_dpll_n = HW_DPLL_4;2116 channel->dpll_phase = DPLL_PHASE_4;2117 channel->dpll_ctrl_n = DPLL_CTRL_4;2118 channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_4;2119 break;2120 case 5:2121 channel->dpll_freq = DPLL_FREQ_5;2122 channel->dpll_n = DPLL_5;2123 channel->hw_dpll_n = HW_DPLL_5;2124 channel->dpll_phase = DPLL_PHASE_5;2125 channel->dpll_ctrl_n = DPLL_CTRL_5;2126 channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_5;2127 break;2128 case 6:2129 channel->dpll_freq = DPLL_FREQ_6;2130 channel->dpll_n = IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_6);2131 channel->hw_dpll_n = HW_DPLL_6;2132 channel->dpll_phase = DPLL_PHASE_6;2133 channel->dpll_ctrl_n = DPLL_CTRL_6;2134 channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_6;2135 break;2136 case 7:2137 channel->dpll_freq = DPLL_FREQ_7;2138 channel->dpll_n = DPLL_7;2139 channel->hw_dpll_n = HW_DPLL_7;2140 channel->dpll_phase = DPLL_PHASE_7;2141 channel->dpll_ctrl_n = DPLL_CTRL_7;2142 channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_7;2143 break;2144 default:2145 err = -EINVAL;2146 }2147 2148 return err;2149}2150 2151/*2152 * Compensate for the PTP DCO input-to-output delay.2153 * This delay is 18 FOD cycles.2154 */2155static u32 idtcm_get_dco_delay(struct idtcm_channel *channel)2156{2157 struct idtcm *idtcm = channel->idtcm;2158 u8 mbuf[8] = {0};2159 u8 nbuf[2] = {0};2160 u32 fodFreq;2161 int err;2162 u64 m;2163 u16 n;2164 2165 err = idtcm_read(idtcm, channel->dpll_ctrl_n,2166 DPLL_CTRL_DPLL_FOD_FREQ, mbuf, 6);2167 if (err)2168 return 0;2169 2170 err = idtcm_read(idtcm, channel->dpll_ctrl_n,2171 DPLL_CTRL_DPLL_FOD_FREQ + 6, nbuf, 2);2172 if (err)2173 return 0;2174 2175 m = get_unaligned_le64(mbuf);2176 n = get_unaligned_le16(nbuf);2177 2178 if (n == 0)2179 n = 1;2180 2181 fodFreq = (u32)div_u64(m, n);2182 2183 if (fodFreq >= 500000000)2184 return (u32)div_u64(18 * (u64)NSEC_PER_SEC, fodFreq);2185 2186 return 0;2187}2188 2189static int configure_channel_tod(struct idtcm_channel *channel, u32 index)2190{2191 enum fw_version fw_ver = channel->idtcm->fw_ver;2192 2193 /* Set tod addresses */2194 switch (index) {2195 case 0:2196 channel->tod_read_primary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_PRIMARY_0);2197 channel->tod_read_secondary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_SECONDARY_0);2198 channel->tod_write = IDTCM_FW_REG(fw_ver, V520, TOD_WRITE_0);2199 channel->tod_n = IDTCM_FW_REG(fw_ver, V520, TOD_0);2200 channel->sync_src = SYNC_SOURCE_DPLL0_TOD_PPS;2201 break;2202 case 1:2203 channel->tod_read_primary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_PRIMARY_1);2204 channel->tod_read_secondary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_SECONDARY_1);2205 channel->tod_write = IDTCM_FW_REG(fw_ver, V520, TOD_WRITE_1);2206 channel->tod_n = IDTCM_FW_REG(fw_ver, V520, TOD_1);2207 channel->sync_src = SYNC_SOURCE_DPLL1_TOD_PPS;2208 break;2209 case 2:2210 channel->tod_read_primary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_PRIMARY_2);2211 channel->tod_read_secondary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_SECONDARY_2);2212 channel->tod_write = IDTCM_FW_REG(fw_ver, V520, TOD_WRITE_2);2213 channel->tod_n = IDTCM_FW_REG(fw_ver, V520, TOD_2);2214 channel->sync_src = SYNC_SOURCE_DPLL2_TOD_PPS;2215 break;2216 case 3:2217 channel->tod_read_primary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_PRIMARY_3);2218 channel->tod_read_secondary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_SECONDARY_3);2219 channel->tod_write = IDTCM_FW_REG(fw_ver, V520, TOD_WRITE_3);2220 channel->tod_n = IDTCM_FW_REG(fw_ver, V520, TOD_3);2221 channel->sync_src = SYNC_SOURCE_DPLL3_TOD_PPS;2222 break;2223 default:2224 return -EINVAL;2225 }2226 2227 return 0;2228}2229 2230static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)2231{2232 struct idtcm_channel *channel;2233 int err;2234 int i;2235 2236 if (!(index < MAX_TOD))2237 return -EINVAL;2238 2239 channel = &idtcm->channel[index];2240 2241 channel->idtcm = idtcm;2242 channel->current_freq_scaled_ppm = 0;2243 2244 /* Set pll addresses */2245 err = configure_channel_pll(channel);2246 if (err)2247 return err;2248 2249 /* Set tod addresses */2250 err = configure_channel_tod(channel, index);2251 if (err)2252 return err;2253 2254 if (idtcm->fw_ver < V487)2255 channel->caps = idtcm_caps_deprecated;2256 else2257 channel->caps = idtcm_caps;2258 2259 snprintf(channel->caps.name, sizeof(channel->caps.name),2260 "IDT CM TOD%u", index);2261 2262 channel->caps.pin_config = pin_config[index];2263 2264 for (i = 0; i < channel->caps.n_pins; ++i) {2265 struct ptp_pin_desc *ppd = &channel->caps.pin_config[i];2266 2267 snprintf(ppd->name, sizeof(ppd->name), "input_ref%d", i);2268 ppd->index = i;2269 ppd->func = PTP_PF_NONE;2270 ppd->chan = index;2271 }2272 2273 err = initialize_dco_operating_mode(channel);2274 if (err)2275 return err;2276 2277 err = idtcm_enable_tod(channel);2278 if (err) {2279 dev_err(idtcm->dev,2280 "Failed at line %d in %s!", __LINE__, __func__);2281 return err;2282 }2283 2284 channel->dco_delay = idtcm_get_dco_delay(channel);2285 2286 channel->ptp_clock = ptp_clock_register(&channel->caps, NULL);2287 2288 if (IS_ERR(channel->ptp_clock)) {2289 err = PTR_ERR(channel->ptp_clock);2290 channel->ptp_clock = NULL;2291 return err;2292 }2293 2294 if (!channel->ptp_clock)2295 return -ENOTSUPP;2296 2297 dev_info(idtcm->dev, "PLL%d registered as ptp%d",2298 index, channel->ptp_clock->index);2299 2300 return 0;2301}2302 2303static int idtcm_enable_extts_channel(struct idtcm *idtcm, u32 index)2304{2305 struct idtcm_channel *channel;2306 int err;2307 2308 if (!(index < MAX_TOD))2309 return -EINVAL;2310 2311 channel = &idtcm->channel[index];2312 channel->idtcm = idtcm;2313 2314 /* Set tod addresses */2315 err = configure_channel_tod(channel, index);2316 if (err)2317 return err;2318 2319 channel->idtcm = idtcm;2320 2321 return 0;2322}2323 2324static void idtcm_extts_check(struct work_struct *work)2325{2326 struct idtcm *idtcm = container_of(work, struct idtcm, extts_work.work);2327 struct idtcm_channel *channel;2328 u8 mask;2329 int err;2330 int i;2331 2332 if (idtcm->extts_mask == 0)2333 return;2334 2335 mutex_lock(idtcm->lock);2336 2337 for (i = 0; i < MAX_TOD; i++) {2338 mask = 1 << i;2339 2340 if ((idtcm->extts_mask & mask) == 0)2341 continue;2342 2343 err = idtcm_extts_check_channel(idtcm, i);2344 2345 if (err == 0) {2346 /* trigger clears itself, so clear the mask */2347 if (idtcm->extts_single_shot) {2348 idtcm->extts_mask &= ~mask;2349 } else {2350 /* Re-arm */2351 channel = &idtcm->channel[i];2352 arm_tod_read_trig_sel_refclk(channel, channel->refn);2353 }2354 }2355 }2356 2357 if (idtcm->extts_mask)2358 schedule_delayed_work(&idtcm->extts_work,2359 msecs_to_jiffies(EXTTS_PERIOD_MS));2360 2361 mutex_unlock(idtcm->lock);2362}2363 2364static void ptp_clock_unregister_all(struct idtcm *idtcm)2365{2366 u8 i;2367 struct idtcm_channel *channel;2368 2369 for (i = 0; i < MAX_TOD; i++) {2370 channel = &idtcm->channel[i];2371 if (channel->ptp_clock)2372 ptp_clock_unregister(channel->ptp_clock);2373 }2374}2375 2376static void set_default_masks(struct idtcm *idtcm)2377{2378 idtcm->tod_mask = DEFAULT_TOD_MASK;2379 idtcm->extts_mask = 0;2380 2381 idtcm->channel[0].tod = 0;2382 idtcm->channel[1].tod = 1;2383 idtcm->channel[2].tod = 2;2384 idtcm->channel[3].tod = 3;2385 2386 idtcm->channel[0].pll = DEFAULT_TOD0_PTP_PLL;2387 idtcm->channel[1].pll = DEFAULT_TOD1_PTP_PLL;2388 idtcm->channel[2].pll = DEFAULT_TOD2_PTP_PLL;2389 idtcm->channel[3].pll = DEFAULT_TOD3_PTP_PLL;2390 2391 idtcm->channel[0].output_mask = DEFAULT_OUTPUT_MASK_PLL0;2392 idtcm->channel[1].output_mask = DEFAULT_OUTPUT_MASK_PLL1;2393 idtcm->channel[2].output_mask = DEFAULT_OUTPUT_MASK_PLL2;2394 idtcm->channel[3].output_mask = DEFAULT_OUTPUT_MASK_PLL3;2395}2396 2397static int idtcm_probe(struct platform_device *pdev)2398{2399 struct rsmu_ddata *ddata = dev_get_drvdata(pdev->dev.parent);2400 struct idtcm *idtcm;2401 int err;2402 u8 i;2403 2404 idtcm = devm_kzalloc(&pdev->dev, sizeof(struct idtcm), GFP_KERNEL);2405 2406 if (!idtcm)2407 return -ENOMEM;2408 2409 idtcm->dev = &pdev->dev;2410 idtcm->mfd = pdev->dev.parent;2411 idtcm->lock = &ddata->lock;2412 idtcm->regmap = ddata->regmap;2413 idtcm->calculate_overhead_flag = 0;2414 2415 INIT_DELAYED_WORK(&idtcm->extts_work, idtcm_extts_check);2416 2417 set_default_masks(idtcm);2418 2419 mutex_lock(idtcm->lock);2420 2421 idtcm_set_version_info(idtcm);2422 2423 err = idtcm_load_firmware(idtcm, &pdev->dev);2424 2425 if (err)2426 dev_warn(idtcm->dev, "loading firmware failed with %d", err);2427 2428 wait_for_chip_ready(idtcm);2429 2430 if (idtcm->tod_mask) {2431 for (i = 0; i < MAX_TOD; i++) {2432 if (idtcm->tod_mask & (1 << i))2433 err = idtcm_enable_channel(idtcm, i);2434 else2435 err = idtcm_enable_extts_channel(idtcm, i);2436 if (err) {2437 dev_err(idtcm->dev,2438 "idtcm_enable_channel %d failed!", i);2439 break;2440 }2441 }2442 } else {2443 dev_err(idtcm->dev,2444 "no PLLs flagged as PHCs, nothing to do");2445 err = -ENODEV;2446 }2447 2448 mutex_unlock(idtcm->lock);2449 2450 if (err) {2451 ptp_clock_unregister_all(idtcm);2452 return err;2453 }2454 2455 platform_set_drvdata(pdev, idtcm);2456 2457 return 0;2458}2459 2460static void idtcm_remove(struct platform_device *pdev)2461{2462 struct idtcm *idtcm = platform_get_drvdata(pdev);2463 2464 idtcm->extts_mask = 0;2465 ptp_clock_unregister_all(idtcm);2466 cancel_delayed_work_sync(&idtcm->extts_work);2467}2468 2469static struct platform_driver idtcm_driver = {2470 .driver = {2471 .name = "8a3400x-phc",2472 },2473 .probe = idtcm_probe,2474 .remove_new = idtcm_remove,2475};2476 2477module_platform_driver(idtcm_driver);2478