Lines Matching refs:idtfc3
38 static s64 ns2counters(struct idtfc3 *idtfc3, s64 nsec, u32 *sub_ns) in ns2counters() argument
44 sync = div_u64_rem(nsec, idtfc3->ns_per_sync, &rem); in ns2counters()
47 sync = -div_u64_rem(-nsec - 1, idtfc3->ns_per_sync, &rem) - 1; in ns2counters()
48 *sub_ns = idtfc3->ns_per_sync - rem - 1; in ns2counters()
51 return sync * idtfc3->ns_per_sync; in ns2counters()
54 static s64 tdc_meas2offset(struct idtfc3 *idtfc3, u64 meas_read) in tdc_meas2offset() argument
61 fine = div64_s64(fine * NSEC_PER_SEC, idtfc3->tdc_apll_freq * 62LL); in tdc_meas2offset()
62 coarse = div64_s64(coarse * NSEC_PER_SEC, idtfc3->time_ref_freq); in tdc_meas2offset()
67 static s64 tdc_offset2phase(struct idtfc3 *idtfc3, s64 offset_ns) in tdc_offset2phase() argument
69 if (offset_ns > idtfc3->ns_per_sync / 2) in tdc_offset2phase()
70 offset_ns -= idtfc3->ns_per_sync; in tdc_offset2phase()
72 return offset_ns * idtfc3->tdc_offset_sign; in tdc_offset2phase()
75 static int idtfc3_set_lpf_mode(struct idtfc3 *idtfc3, u8 mode) in idtfc3_set_lpf_mode() argument
82 if (idtfc3->lpf_mode == mode) in idtfc3_set_lpf_mode()
85 err = regmap_bulk_write(idtfc3->regmap, LPF_MODE_CNFG, &mode, sizeof(mode)); in idtfc3_set_lpf_mode()
89 idtfc3->lpf_mode = mode; in idtfc3_set_lpf_mode()
94 static int idtfc3_enable_lpf(struct idtfc3 *idtfc3, bool enable) in idtfc3_enable_lpf() argument
99 err = regmap_bulk_read(idtfc3->regmap, LPF_CTRL, &val, sizeof(val)); in idtfc3_enable_lpf()
108 return regmap_bulk_write(idtfc3->regmap, LPF_CTRL, &val, sizeof(val)); in idtfc3_enable_lpf()
111 static int idtfc3_get_time_ref_freq(struct idtfc3 *idtfc3) in idtfc3_get_time_ref_freq() argument
118 err = regmap_bulk_read(idtfc3->regmap, TIME_CLOCK_MEAS_DIV_CNFG, buf, sizeof(buf)); in idtfc3_get_time_ref_freq()
123 err = regmap_bulk_read(idtfc3->regmap, TIME_CLOCK_COUNT, buf, 1); in idtfc3_get_time_ref_freq()
127 idtfc3->time_ref_freq = idtfc3->hw_param.time_clk_freq * in idtfc3_get_time_ref_freq()
133 static int idtfc3_get_tdc_offset_sign(struct idtfc3 *idtfc3) in idtfc3_get_tdc_offset_sign() argument
140 err = regmap_bulk_read(idtfc3->regmap, TIME_CLOCK_TDC_FANOUT_CNFG, buf, sizeof(buf)); in idtfc3_get_tdc_offset_sign()
146 dev_err(idtfc3->dev, "TIME_SYNC_TO_TDC_EN is off !!!"); in idtfc3_get_tdc_offset_sign()
154 dev_err(idtfc3->dev, "Invalid tdc_mux_sel sig1=%d sig2=%d", sig1, sig2); in idtfc3_get_tdc_offset_sign()
157 idtfc3->tdc_offset_sign = 1; in idtfc3_get_tdc_offset_sign()
159 idtfc3->tdc_offset_sign = -1; in idtfc3_get_tdc_offset_sign()
165 static int idtfc3_lpf_bw(struct idtfc3 *idtfc3, u8 shift, u8 mult) in idtfc3_lpf_bw() argument
169 return regmap_bulk_write(idtfc3->regmap, LPF_BW_CNFG, &val, sizeof(val)); in idtfc3_lpf_bw()
172 static int idtfc3_enable_tdc(struct idtfc3 *idtfc3, bool enable, u8 meas_mode) in idtfc3_enable_tdc() argument
178 err = regmap_bulk_write(idtfc3->regmap, TIME_CLOCK_MEAS_CTRL, &val, sizeof(val)); in idtfc3_enable_tdc()
183 return idtfc3_lpf_bw(idtfc3, LPF_BW_SHIFT_DEFAULT, LPF_BW_MULT_DEFAULT); in idtfc3_enable_tdc()
189 err = regmap_bulk_write(idtfc3->regmap, TIME_CLOCK_MEAS_CNFG, in idtfc3_enable_tdc()
198 err = regmap_bulk_write(idtfc3->regmap, TIME_CLOCK_MEAS_CTRL, &val, sizeof(val)); in idtfc3_enable_tdc()
202 return idtfc3_lpf_bw(idtfc3, LPF_BW_SHIFT_1PPS, LPF_BW_MULT_DEFAULT); in idtfc3_enable_tdc()
205 static bool get_tdc_meas(struct idtfc3 *idtfc3, s64 *offset_ns) in get_tdc_meas() argument
213 err = regmap_bulk_read(idtfc3->regmap, TDC_FIFO_STS, in get_tdc_meas()
221 err = regmap_bulk_read(idtfc3->regmap, TDC_FIFO_READ_REQ, in get_tdc_meas()
230 *offset_ns = tdc_meas2offset(idtfc3, get_unaligned_le64(&buf[1])); in get_tdc_meas()
235 static int check_tdc_fifo_overrun(struct idtfc3 *idtfc3) in check_tdc_fifo_overrun() argument
241 err = regmap_bulk_read(idtfc3->regmap, TDC_FIFO_STS, &val, sizeof(val)); in check_tdc_fifo_overrun()
248 dev_warn(idtfc3->dev, "TDC FIFO overrun !!!"); in check_tdc_fifo_overrun()
250 err = idtfc3_enable_tdc(idtfc3, true, CONTINUOUS); in check_tdc_fifo_overrun()
257 static int get_tdc_meas_continuous(struct idtfc3 *idtfc3) in get_tdc_meas_continuous() argument
263 err = check_tdc_fifo_overrun(idtfc3); in get_tdc_meas_continuous()
267 if (get_tdc_meas(idtfc3, &offset_ns) && offset_ns >= 0) { in get_tdc_meas_continuous()
269 event.offset = tdc_offset2phase(idtfc3, offset_ns); in get_tdc_meas_continuous()
271 ptp_clock_event(idtfc3->ptp_clock, &event); in get_tdc_meas_continuous()
277 static int idtfc3_read_subcounter(struct idtfc3 *idtfc3) in idtfc3_read_subcounter() argument
282 err = regmap_bulk_read(idtfc3->regmap, TOD_COUNTER_READ_REQ, in idtfc3_read_subcounter()
291 static int idtfc3_tod_update_is_done(struct idtfc3 *idtfc3) in idtfc3_tod_update_is_done() argument
297 idtfc3->tc_write_timeout, true, idtfc3->regmap, in idtfc3_tod_update_is_done()
300 dev_err(idtfc3->dev, "TOD counter write timeout !!!"); in idtfc3_tod_update_is_done()
305 static int idtfc3_write_subcounter(struct idtfc3 *idtfc3, u32 counter) in idtfc3_write_subcounter() argument
316 err = regmap_bulk_write(idtfc3->regmap, TOD_SYNC_LOAD_VAL_CTRL, in idtfc3_write_subcounter()
321 return idtfc3_tod_update_is_done(idtfc3); in idtfc3_write_subcounter()
324 static int idtfc3_timecounter_update(struct idtfc3 *idtfc3, u32 counter, s64 ns) in idtfc3_timecounter_update() argument
328 err = idtfc3_write_subcounter(idtfc3, counter); in idtfc3_timecounter_update()
333 idtfc3->ns = ns; in idtfc3_timecounter_update()
334 idtfc3->last_counter = counter; in idtfc3_timecounter_update()
339 static int idtfc3_timecounter_read(struct idtfc3 *idtfc3) in idtfc3_timecounter_read() argument
343 now = idtfc3_read_subcounter(idtfc3); in idtfc3_timecounter_read()
348 if (now >= idtfc3->last_counter) in idtfc3_timecounter_read()
349 delta = now - idtfc3->last_counter; in idtfc3_timecounter_read()
351 delta = idtfc3->sub_sync_count - idtfc3->last_counter + now; in idtfc3_timecounter_read()
354 idtfc3->ns += delta * idtfc3->ns_per_counter; in idtfc3_timecounter_read()
355 idtfc3->last_counter = now; in idtfc3_timecounter_read()
360 static int _idtfc3_gettime(struct idtfc3 *idtfc3, struct timespec64 *ts) in _idtfc3_gettime() argument
364 err = idtfc3_timecounter_read(idtfc3); in _idtfc3_gettime()
368 *ts = ns_to_timespec64(idtfc3->ns); in _idtfc3_gettime()
375 struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps); in idtfc3_gettime() local
378 mutex_lock(idtfc3->lock); in idtfc3_gettime()
379 err = _idtfc3_gettime(idtfc3, ts); in idtfc3_gettime()
380 mutex_unlock(idtfc3->lock); in idtfc3_gettime()
385 static int _idtfc3_settime(struct idtfc3 *idtfc3, const struct timespec64 *ts) in _idtfc3_settime() argument
392 dev_err(idtfc3->dev, "%s: invalid timespec", __func__); in _idtfc3_settime()
396 now = idtfc3_read_subcounter(idtfc3); in _idtfc3_settime()
400 offset_ns = (idtfc3->sub_sync_count - now) * idtfc3->ns_per_counter; in _idtfc3_settime()
402 (void)ns2counters(idtfc3, offset_ns + now_ns, &sub_ns); in _idtfc3_settime()
404 counter = sub_ns / idtfc3->ns_per_counter; in _idtfc3_settime()
405 return idtfc3_timecounter_update(idtfc3, counter, now_ns); in _idtfc3_settime()
410 struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps); in idtfc3_settime() local
413 mutex_lock(idtfc3->lock); in idtfc3_settime()
414 err = _idtfc3_settime(idtfc3, ts); in idtfc3_settime()
415 mutex_unlock(idtfc3->lock); in idtfc3_settime()
420 static int _idtfc3_adjtime(struct idtfc3 *idtfc3, s64 delta) in _idtfc3_adjtime() argument
430 if (idtfc3->ns + delta < 0) { in _idtfc3_adjtime()
431 dev_err(idtfc3->dev, "%lld ns adj is too large", delta); in _idtfc3_adjtime()
435 sync_ns = ns2counters(idtfc3, delta + idtfc3->ns_per_sync, &sub_ns); in _idtfc3_adjtime()
437 counter = sub_ns / idtfc3->ns_per_counter; in _idtfc3_adjtime()
438 return idtfc3_timecounter_update(idtfc3, counter, idtfc3->ns + sync_ns + in _idtfc3_adjtime()
439 counter * idtfc3->ns_per_counter); in _idtfc3_adjtime()
444 struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps); in idtfc3_adjtime() local
447 mutex_lock(idtfc3->lock); in idtfc3_adjtime()
448 err = _idtfc3_adjtime(idtfc3, delta); in idtfc3_adjtime()
449 mutex_unlock(idtfc3->lock); in idtfc3_adjtime()
454 static int _idtfc3_adjphase(struct idtfc3 *idtfc3, s32 delta) in _idtfc3_adjphase() argument
460 err = idtfc3_set_lpf_mode(idtfc3, LPF_WP); in _idtfc3_adjphase()
472 pcw = div_s64((s64)delta * idtfc3->tdc_apll_freq * 124, NSEC_PER_SEC); in _idtfc3_adjphase()
476 return regmap_bulk_write(idtfc3->regmap, LPF_WR_PHASE_CTRL, buf, sizeof(buf)); in _idtfc3_adjphase()
481 struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps); in idtfc3_adjphase() local
484 mutex_lock(idtfc3->lock); in idtfc3_adjphase()
485 err = _idtfc3_adjphase(idtfc3, delta); in idtfc3_adjphase()
486 mutex_unlock(idtfc3->lock); in idtfc3_adjphase()
491 static int _idtfc3_adjfine(struct idtfc3 *idtfc3, long scaled_ppm) in _idtfc3_adjfine() argument
497 err = idtfc3_set_lpf_mode(idtfc3, LPF_WF); in _idtfc3_adjfine()
519 return regmap_bulk_write(idtfc3->regmap, LPF_WR_FREQ_CTRL, buf, sizeof(buf)); in _idtfc3_adjfine()
524 struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps); in idtfc3_adjfine() local
527 mutex_lock(idtfc3->lock); in idtfc3_adjfine()
528 err = _idtfc3_adjfine(idtfc3, scaled_ppm); in idtfc3_adjfine()
529 mutex_unlock(idtfc3->lock); in idtfc3_adjfine()
537 struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps); in idtfc3_enable() local
540 mutex_lock(idtfc3->lock); in idtfc3_enable()
558 err = idtfc3_enable_tdc(idtfc3, true, CONTINUOUS); in idtfc3_enable()
560 err = idtfc3_enable_tdc(idtfc3, false, MEAS_MODE_INVALID); in idtfc3_enable()
566 mutex_unlock(idtfc3->lock); in idtfc3_enable()
569 dev_err(idtfc3->dev, "Failed in %s with err %d!", __func__, err); in idtfc3_enable()
576 struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps); in idtfc3_aux_work() local
579 mutex_lock(idtfc3->lock); in idtfc3_aux_work()
582 idtfc3_timecounter_read(idtfc3); in idtfc3_aux_work()
583 get_tdc_meas_continuous(idtfc3); in idtfc3_aux_work()
585 mutex_unlock(idtfc3->lock); in idtfc3_aux_work()
587 return idtfc3->tc_update_period; in idtfc3_aux_work()
604 static int idtfc3_hw_calibrate(struct idtfc3 *idtfc3) in idtfc3_hw_calibrate() argument
617 err = regmap_bulk_write(idtfc3->regmap, TDC_CTRL, in idtfc3_hw_calibrate()
622 err = regmap_bulk_write(idtfc3->regmap, TDC_CTRL, in idtfc3_hw_calibrate()
634 err = regmap_bulk_write(idtfc3->regmap, SOFT_RESET_CTRL, in idtfc3_hw_calibrate()
639 err = regmap_bulk_write(idtfc3->regmap, SOFT_RESET_CTRL, in idtfc3_hw_calibrate()
648 static int idtfc3_init_timecounter(struct idtfc3 *idtfc3) in idtfc3_init_timecounter() argument
653 period_ms = idtfc3->sub_sync_count * MSEC_PER_SEC / in idtfc3_init_timecounter()
654 idtfc3->hw_param.time_clk_freq; in idtfc3_init_timecounter()
656 idtfc3->tc_update_period = msecs_to_jiffies(period_ms / TDC_GET_PERIOD); in idtfc3_init_timecounter()
657 idtfc3->tc_write_timeout = period_ms * USEC_PER_MSEC; in idtfc3_init_timecounter()
659 err = idtfc3_timecounter_update(idtfc3, 0, 0); in idtfc3_init_timecounter()
663 err = idtfc3_timecounter_read(idtfc3); in idtfc3_init_timecounter()
667 ptp_schedule_worker(idtfc3->ptp_clock, idtfc3->tc_update_period); in idtfc3_init_timecounter()
672 static int idtfc3_get_tdc_apll_freq(struct idtfc3 *idtfc3) in idtfc3_get_tdc_apll_freq() argument
677 struct idtfc3_hw_param *param = &idtfc3->hw_param; in idtfc3_get_tdc_apll_freq()
679 err = regmap_bulk_read(idtfc3->regmap, TDC_REF_DIV_CNFG, in idtfc3_get_tdc_apll_freq()
684 err = regmap_bulk_read(idtfc3->regmap, TDC_FB_DIV_INT_CNFG, in idtfc3_get_tdc_apll_freq()
692 idtfc3->tdc_apll_freq = div_u64(param->xtal_freq * (u64)tdc_fb_div_int, in idtfc3_get_tdc_apll_freq()
698 static int idtfc3_get_fod(struct idtfc3 *idtfc3) in idtfc3_get_fod() argument
703 err = regmap_bulk_read(idtfc3->regmap, TIME_CLOCK_SRC, &fod, sizeof(fod)); in idtfc3_get_fod()
709 idtfc3->fod_n = FOD_0; in idtfc3_get_fod()
712 idtfc3->fod_n = FOD_1; in idtfc3_get_fod()
715 idtfc3->fod_n = FOD_2; in idtfc3_get_fod()
724 static int idtfc3_get_sync_count(struct idtfc3 *idtfc3) in idtfc3_get_sync_count() argument
729 err = regmap_bulk_read(idtfc3->regmap, SUB_SYNC_GEN_CNFG, buf, sizeof(buf)); in idtfc3_get_sync_count()
733 idtfc3->sub_sync_count = (get_unaligned_le32(buf) & SUB_SYNC_COUNTER_MASK) + 1; in idtfc3_get_sync_count()
734 idtfc3->ns_per_counter = NSEC_PER_SEC / idtfc3->hw_param.time_clk_freq; in idtfc3_get_sync_count()
735 idtfc3->ns_per_sync = idtfc3->sub_sync_count * idtfc3->ns_per_counter; in idtfc3_get_sync_count()
740 static int idtfc3_setup_hw_param(struct idtfc3 *idtfc3) in idtfc3_setup_hw_param() argument
744 err = idtfc3_get_fod(idtfc3); in idtfc3_setup_hw_param()
748 err = idtfc3_get_sync_count(idtfc3); in idtfc3_setup_hw_param()
752 err = idtfc3_get_time_ref_freq(idtfc3); in idtfc3_setup_hw_param()
756 return idtfc3_get_tdc_apll_freq(idtfc3); in idtfc3_setup_hw_param()
759 static int idtfc3_configure_hw(struct idtfc3 *idtfc3) in idtfc3_configure_hw() argument
763 err = idtfc3_hw_calibrate(idtfc3); in idtfc3_configure_hw()
767 err = idtfc3_enable_lpf(idtfc3, true); in idtfc3_configure_hw()
771 err = idtfc3_enable_tdc(idtfc3, false, MEAS_MODE_INVALID); in idtfc3_configure_hw()
775 err = idtfc3_get_tdc_offset_sign(idtfc3); in idtfc3_configure_hw()
779 return idtfc3_setup_hw_param(idtfc3); in idtfc3_configure_hw()
782 static int idtfc3_set_overhead(struct idtfc3 *idtfc3) in idtfc3_set_overhead() argument
797 err = regmap_bulk_write(idtfc3->regmap, TOD_SYNC_LOAD_VAL_CTRL, in idtfc3_set_overhead()
816 idtfc3->tod_write_overhead = lowest_ns; in idtfc3_set_overhead()
821 static int idtfc3_enable_ptp(struct idtfc3 *idtfc3) in idtfc3_enable_ptp() argument
825 idtfc3->caps = idtfc3_caps; in idtfc3_enable_ptp()
826 snprintf(idtfc3->caps.name, sizeof(idtfc3->caps.name), "IDT FC3W"); in idtfc3_enable_ptp()
827 idtfc3->ptp_clock = ptp_clock_register(&idtfc3->caps, NULL); in idtfc3_enable_ptp()
829 if (IS_ERR(idtfc3->ptp_clock)) { in idtfc3_enable_ptp()
830 err = PTR_ERR(idtfc3->ptp_clock); in idtfc3_enable_ptp()
831 idtfc3->ptp_clock = NULL; in idtfc3_enable_ptp()
835 err = idtfc3_set_overhead(idtfc3); in idtfc3_enable_ptp()
839 err = idtfc3_init_timecounter(idtfc3); in idtfc3_enable_ptp()
843 dev_info(idtfc3->dev, "TIME_SYNC_CHANNEL registered as ptp%d", in idtfc3_enable_ptp()
844 idtfc3->ptp_clock->index); in idtfc3_enable_ptp()
849 static int idtfc3_load_firmware(struct idtfc3 *idtfc3) in idtfc3_load_firmware() argument
859 idtfc3_default_hw_param(&idtfc3->hw_param); in idtfc3_load_firmware()
864 dev_info(idtfc3->dev, "requesting firmware '%s'\n", fname); in idtfc3_load_firmware()
866 err = request_firmware(&fw, fname, idtfc3->dev); in idtfc3_load_firmware()
869 dev_err(idtfc3->dev, in idtfc3_load_firmware()
874 dev_dbg(idtfc3->dev, "firmware size %zu bytes\n", fw->size); in idtfc3_load_firmware()
880 dev_err(idtfc3->dev, in idtfc3_load_firmware()
889 err = idtfc3_set_hw_param(&idtfc3->hw_param, addr, val); in idtfc3_load_firmware()
899 err = regmap_bulk_write(idtfc3->regmap, addr, in idtfc3_load_firmware()
907 err = idtfc3_configure_hw(idtfc3); in idtfc3_load_firmware()
913 static int idtfc3_read_device_id(struct idtfc3 *idtfc3, u16 *device_id) in idtfc3_read_device_id() argument
918 err = regmap_bulk_read(idtfc3->regmap, DEVICE_ID, in idtfc3_read_device_id()
921 dev_err(idtfc3->dev, "%s failed with %d", __func__, err); in idtfc3_read_device_id()
930 static int idtfc3_check_device_compatibility(struct idtfc3 *idtfc3) in idtfc3_check_device_compatibility() argument
935 err = idtfc3_read_device_id(idtfc3, &device_id); in idtfc3_check_device_compatibility()
940 dev_err(idtfc3->dev, "invalid device"); in idtfc3_check_device_compatibility()
950 struct idtfc3 *idtfc3; in idtfc3_probe() local
953 idtfc3 = devm_kzalloc(&pdev->dev, sizeof(struct idtfc3), GFP_KERNEL); in idtfc3_probe()
955 if (!idtfc3) in idtfc3_probe()
958 idtfc3->dev = &pdev->dev; in idtfc3_probe()
959 idtfc3->mfd = pdev->dev.parent; in idtfc3_probe()
960 idtfc3->lock = &ddata->lock; in idtfc3_probe()
961 idtfc3->regmap = ddata->regmap; in idtfc3_probe()
963 mutex_lock(idtfc3->lock); in idtfc3_probe()
965 err = idtfc3_check_device_compatibility(idtfc3); in idtfc3_probe()
967 mutex_unlock(idtfc3->lock); in idtfc3_probe()
971 err = idtfc3_load_firmware(idtfc3); in idtfc3_probe()
974 mutex_unlock(idtfc3->lock); in idtfc3_probe()
977 dev_warn(idtfc3->dev, "loading firmware failed with %d", err); in idtfc3_probe()
980 err = idtfc3_enable_ptp(idtfc3); in idtfc3_probe()
982 dev_err(idtfc3->dev, "idtfc3_enable_ptp failed with %d", err); in idtfc3_probe()
983 mutex_unlock(idtfc3->lock); in idtfc3_probe()
987 mutex_unlock(idtfc3->lock); in idtfc3_probe()
990 ptp_clock_unregister(idtfc3->ptp_clock); in idtfc3_probe()
994 platform_set_drvdata(pdev, idtfc3); in idtfc3_probe()
1001 struct idtfc3 *idtfc3 = platform_get_drvdata(pdev); in idtfc3_remove() local
1003 ptp_clock_unregister(idtfc3->ptp_clock); in idtfc3_remove()