18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * PTP hardware clock driver for the IDT ClockMatrix(TM) family of timing and
48c2ecf20Sopenharmony_ci * synchronization devices.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2019 Integrated Device Technology, Inc., a Renesas Company.
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci#ifndef PTP_IDTCLOCKMATRIX_H
98c2ecf20Sopenharmony_ci#define PTP_IDTCLOCKMATRIX_H
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/ktime.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include "idt8a340_reg.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define FW_FILENAME	"idtcm.bin"
168c2ecf20Sopenharmony_ci#define MAX_TOD		(4)
178c2ecf20Sopenharmony_ci#define MAX_PLL		(8)
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#define MAX_ABS_WRITE_PHASE_PICOSECONDS (107374182350LL)
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#define TOD_MASK_ADDR		(0xFFA5)
228c2ecf20Sopenharmony_ci#define DEFAULT_TOD_MASK	(0x04)
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#define SET_U16_LSB(orig, val8) (orig = (0xff00 & (orig)) | (val8))
258c2ecf20Sopenharmony_ci#define SET_U16_MSB(orig, val8) (orig = (0x00ff & (orig)) | (val8 << 8))
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#define TOD0_PTP_PLL_ADDR		(0xFFA8)
288c2ecf20Sopenharmony_ci#define TOD1_PTP_PLL_ADDR		(0xFFA9)
298c2ecf20Sopenharmony_ci#define TOD2_PTP_PLL_ADDR		(0xFFAA)
308c2ecf20Sopenharmony_ci#define TOD3_PTP_PLL_ADDR		(0xFFAB)
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci#define TOD0_OUT_ALIGN_MASK_ADDR	(0xFFB0)
338c2ecf20Sopenharmony_ci#define TOD1_OUT_ALIGN_MASK_ADDR	(0xFFB2)
348c2ecf20Sopenharmony_ci#define TOD2_OUT_ALIGN_MASK_ADDR	(0xFFB4)
358c2ecf20Sopenharmony_ci#define TOD3_OUT_ALIGN_MASK_ADDR	(0xFFB6)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#define DEFAULT_OUTPUT_MASK_PLL0	(0x003)
388c2ecf20Sopenharmony_ci#define DEFAULT_OUTPUT_MASK_PLL1	(0x00c)
398c2ecf20Sopenharmony_ci#define DEFAULT_OUTPUT_MASK_PLL2	(0x030)
408c2ecf20Sopenharmony_ci#define DEFAULT_OUTPUT_MASK_PLL3	(0x0c0)
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci#define DEFAULT_TOD0_PTP_PLL		(0)
438c2ecf20Sopenharmony_ci#define DEFAULT_TOD1_PTP_PLL		(1)
448c2ecf20Sopenharmony_ci#define DEFAULT_TOD2_PTP_PLL		(2)
458c2ecf20Sopenharmony_ci#define DEFAULT_TOD3_PTP_PLL		(3)
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#define POST_SM_RESET_DELAY_MS		(3000)
488c2ecf20Sopenharmony_ci#define PHASE_PULL_IN_THRESHOLD_NS	(150000)
498c2ecf20Sopenharmony_ci#define PHASE_PULL_IN_THRESHOLD_NS_V487	(15000)
508c2ecf20Sopenharmony_ci#define TOD_WRITE_OVERHEAD_COUNT_MAX	(2)
518c2ecf20Sopenharmony_ci#define TOD_BYTE_COUNT			(11)
528c2ecf20Sopenharmony_ci#define WR_PHASE_SETUP_MS		(5000)
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci#define OUTPUT_MODULE_FROM_INDEX(index)	(OUTPUT_0 + (index) * 0x10)
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci#define PEROUT_ENABLE_OUTPUT_MASK		(0xdeadbeef)
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci#define IDTCM_MAX_WRITE_COUNT			(512)
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci/* Values of DPLL_N.DPLL_MODE.PLL_MODE */
618c2ecf20Sopenharmony_cienum pll_mode {
628c2ecf20Sopenharmony_ci	PLL_MODE_MIN = 0,
638c2ecf20Sopenharmony_ci	PLL_MODE_NORMAL = PLL_MODE_MIN,
648c2ecf20Sopenharmony_ci	PLL_MODE_WRITE_PHASE = 1,
658c2ecf20Sopenharmony_ci	PLL_MODE_WRITE_FREQUENCY = 2,
668c2ecf20Sopenharmony_ci	PLL_MODE_GPIO_INC_DEC = 3,
678c2ecf20Sopenharmony_ci	PLL_MODE_SYNTHESIS = 4,
688c2ecf20Sopenharmony_ci	PLL_MODE_PHASE_MEASUREMENT = 5,
698c2ecf20Sopenharmony_ci	PLL_MODE_DISABLED = 6,
708c2ecf20Sopenharmony_ci	PLL_MODE_MAX = PLL_MODE_DISABLED,
718c2ecf20Sopenharmony_ci};
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cienum hw_tod_write_trig_sel {
748c2ecf20Sopenharmony_ci	HW_TOD_WR_TRIG_SEL_MIN = 0,
758c2ecf20Sopenharmony_ci	HW_TOD_WR_TRIG_SEL_MSB = HW_TOD_WR_TRIG_SEL_MIN,
768c2ecf20Sopenharmony_ci	HW_TOD_WR_TRIG_SEL_RESERVED = 1,
778c2ecf20Sopenharmony_ci	HW_TOD_WR_TRIG_SEL_TOD_PPS = 2,
788c2ecf20Sopenharmony_ci	HW_TOD_WR_TRIG_SEL_IRIGB_PPS = 3,
798c2ecf20Sopenharmony_ci	HW_TOD_WR_TRIG_SEL_PWM_PPS = 4,
808c2ecf20Sopenharmony_ci	HW_TOD_WR_TRIG_SEL_GPIO = 5,
818c2ecf20Sopenharmony_ci	HW_TOD_WR_TRIG_SEL_FOD_SYNC = 6,
828c2ecf20Sopenharmony_ci	WR_TRIG_SEL_MAX = HW_TOD_WR_TRIG_SEL_FOD_SYNC,
838c2ecf20Sopenharmony_ci};
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci/* 4.8.7 only */
868c2ecf20Sopenharmony_cienum scsr_tod_write_trig_sel {
878c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TRIG_SEL_DISABLE = 0,
888c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TRIG_SEL_IMMEDIATE = 1,
898c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TRIG_SEL_REFCLK = 2,
908c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TRIG_SEL_PWMPPS = 3,
918c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TRIG_SEL_TODPPS = 4,
928c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TRIG_SEL_SYNCFOD = 5,
938c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TRIG_SEL_GPIO = 6,
948c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TRIG_SEL_MAX = SCSR_TOD_WR_TRIG_SEL_GPIO,
958c2ecf20Sopenharmony_ci};
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci/* 4.8.7 only */
988c2ecf20Sopenharmony_cienum scsr_tod_write_type_sel {
998c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TYPE_SEL_ABSOLUTE = 0,
1008c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS = 1,
1018c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS = 2,
1028c2ecf20Sopenharmony_ci	SCSR_TOD_WR_TYPE_SEL_MAX = SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS,
1038c2ecf20Sopenharmony_ci};
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistruct idtcm;
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cistruct idtcm_channel {
1088c2ecf20Sopenharmony_ci	struct ptp_clock_info	caps;
1098c2ecf20Sopenharmony_ci	struct ptp_clock	*ptp_clock;
1108c2ecf20Sopenharmony_ci	struct idtcm		*idtcm;
1118c2ecf20Sopenharmony_ci	u16			dpll_phase;
1128c2ecf20Sopenharmony_ci	u16			dpll_freq;
1138c2ecf20Sopenharmony_ci	u16			dpll_n;
1148c2ecf20Sopenharmony_ci	u16			dpll_ctrl_n;
1158c2ecf20Sopenharmony_ci	u16			dpll_phase_pull_in;
1168c2ecf20Sopenharmony_ci	u16			tod_read_primary;
1178c2ecf20Sopenharmony_ci	u16			tod_write;
1188c2ecf20Sopenharmony_ci	u16			tod_n;
1198c2ecf20Sopenharmony_ci	u16			hw_dpll_n;
1208c2ecf20Sopenharmony_ci	enum pll_mode		pll_mode;
1218c2ecf20Sopenharmony_ci	u8			pll;
1228c2ecf20Sopenharmony_ci	u16			output_mask;
1238c2ecf20Sopenharmony_ci	int			write_phase_ready;
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistruct idtcm {
1278c2ecf20Sopenharmony_ci	struct idtcm_channel	channel[MAX_TOD];
1288c2ecf20Sopenharmony_ci	struct i2c_client	*client;
1298c2ecf20Sopenharmony_ci	u8			page_offset;
1308c2ecf20Sopenharmony_ci	u8			tod_mask;
1318c2ecf20Sopenharmony_ci	char			version[16];
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	/* Overhead calculation for adjtime */
1348c2ecf20Sopenharmony_ci	u8			calculate_overhead_flag;
1358c2ecf20Sopenharmony_ci	s64			tod_write_overhead_ns;
1368c2ecf20Sopenharmony_ci	ktime_t			start_time;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	/* Protects I2C read/modify/write registers from concurrent access */
1398c2ecf20Sopenharmony_ci	struct mutex		reg_lock;
1408c2ecf20Sopenharmony_ci};
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_cistruct idtcm_fwrc {
1438c2ecf20Sopenharmony_ci	u8 hiaddr;
1448c2ecf20Sopenharmony_ci	u8 loaddr;
1458c2ecf20Sopenharmony_ci	u8 value;
1468c2ecf20Sopenharmony_ci	u8 reserved;
1478c2ecf20Sopenharmony_ci} __packed;
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci#endif /* PTP_IDTCLOCKMATRIX_H */
150