diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index 942f72d..25b74a2 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -118,6 +118,7 @@ config PTP_1588_CLOCK_KVM
 config PTP_1588_CLOCK_IDT82P33
 	tristate "IDT 82P33xxx PTP clock"
 	depends on PTP_1588_CLOCK && I2C
+	select DEBUG_FS
 	default n
 	help
 	  This driver adds support for using the IDT 82P33xxx as a PTP
@@ -130,6 +131,7 @@ config PTP_1588_CLOCK_IDT82P33
 config PTP_1588_CLOCK_IDTCM
 	tristate "IDT CLOCKMATRIX as PTP clock"
 	depends on PTP_1588_CLOCK && I2C
+	select DEBUG_FS
 	default n
 	help
 	  This driver adds support for using IDT CLOCKMATRIX(TM) as a PTP
diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile
index 7aff75f..a4a9e35 100644
--- a/drivers/ptp/Makefile
+++ b/drivers/ptp/Makefile
@@ -12,6 +12,8 @@ obj-$(CONFIG_PTP_1588_CLOCK_KVM)	+= ptp_kvm.o
 obj-$(CONFIG_PTP_1588_CLOCK_QORIQ)	+= ptp-qoriq.o
 ptp-qoriq-y				+= ptp_qoriq.o
 ptp-qoriq-$(CONFIG_DEBUG_FS)		+= ptp_qoriq_debugfs.o
-obj-$(CONFIG_PTP_1588_CLOCK_IDTCM)	+= ptp_clockmatrix.o
+obj-$(CONFIG_PTP_1588_CLOCK_IDTCM)	+= ptp_idtcm.o
 obj-$(CONFIG_PTP_1588_CLOCK_IDT82P33)	+= ptp_idt82p33.o
 obj-$(CONFIG_PTP_1588_CLOCK_VMW)	+= ptp_vmw.o
+
+ptp_idtcm-objs += ptp_clockmatrix.o ptp_idt_debugfs.o
diff --git a/drivers/ptp/ptp_idt_debugfs.c b/drivers/ptp/ptp_idt_debugfs.c
new file mode 100644
index 0000000..0ae02f7
--- /dev/null
+++ b/drivers/ptp/ptp_idt_debugfs.c
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PTP debugfs interface for the IDT family of timing and
+ * synchronization devices.
+ *
+ * Copyright (C) 2019 Integrated Device Technology, Inc., a Renesas Company.
+ */
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include "ptp_idt_debugfs.h"
+
+MODULE_LICENSE("GPL");
+
+#define DEBUGFS_CMD_MAX_WRITE_SIZE (4)
+#define DEBUGFS_CMD_MENU_SIZE (4)
+#define DEBUGFS_CMD_MAX_SIZE (64)
+#define DEBUGFS_CMD_HELP \
+	"1) set combomode:\n" \
+	"echo -n \"combomode:mode[current/fast/slow/hold]\" > cmd\n" \
+	"2) write up to 4 registers:\n" \
+	"echo -n \"write:addr[hex]:value[hex]:num of bytes[max 4]\" > cmd\n" \
+	"3) show all registers:\n" \
+	"cat regs"
+
+struct idtptp_debugfs {
+	idtptp_debugfs_handle handle;
+	struct ptp_clock_info *info;
+	debugfs_cmd_handler handler;
+	struct idtptp_debugfs_regs space;
+	struct dentry *root;
+	struct dentry *cmd;
+	struct dentry *regs;
+	struct dentry *help;
+};
+
+struct idtptp_debugfs_menu {
+	const char *input[DEBUGFS_CMD_MENU_SIZE];
+	const int output[DEBUGFS_CMD_MENU_SIZE];
+	const int size;
+};
+
+static struct idtptp_debugfs_menu cmdmenu = {
+	.input = {"combomode", "write", "read"},
+	.output = {IDTPTP_DEBUGFS_COMBOMODE,
+		   IDTPTP_DEBUGFS_WRITE_REG,
+		   IDTPTP_DEBUGFS_READ_REG},
+	.size = 3,
+};
+
+static struct idtptp_debugfs_menu combomodemenu = {
+	.input = {"current", "fast", "slow", "hold"},
+	.output = {E_COMBOMODE_CURRENT,
+		   E_COMBOMODE_FASTAVG,
+		   E_COMBOMODE_SLOWAVG,
+		   E_COMBOMODE_HOLDOVER},
+	.size = 4,
+};
+
+static inline int
+idtptp_debugfs_parse_menu(char *input,
+			  struct idtptp_debugfs_menu *menu)
+{
+	int i;
+
+	for (i = 0; i < menu->size; i++) {
+		if (strcmp(input, menu->input[i]) == 0)
+			return menu->output[i];
+	}
+
+	return -EINVAL;
+}
+
+static inline int
+idtptp_debugfs_parse_combomode(char *param,
+			       struct idtptp_debugfs_data *data)
+{
+	char **strp = &param;
+	char *modein;
+
+	modein = strsep(strp, ":");
+	if (modein == NULL)
+		return -EINVAL;
+
+	data->combomode = idtptp_debugfs_parse_menu(modein, &combomodemenu);
+
+	return data->combomode;
+}
+
+static inline int
+idtptp_debugfs_parse_write(char *param,
+			   struct idtptp_debugfs_regs space,
+			   struct idtptp_debugfs_data *data)
+{
+	struct idtptp_debugfs_wr *wr = &data->wr;
+	char *addrin, *valuein, *bytesin;
+	unsigned int addr, value, bytes;
+	char **strp = &param;
+	int ret, i;
+
+	addrin = strsep(strp, ":");
+	if (addrin == NULL)
+		return -EINVAL;
+
+	ret = kstrtouint(addrin, 16, &addr);
+	if (ret < 0)
+		return ret;
+
+	if (addr < space.addr || addr > space.addr + space.length - 1)
+		return -EINVAL;
+
+	valuein = strsep(strp, ":");
+	if (valuein == NULL)
+		return -EINVAL;
+
+	ret = kstrtouint(valuein, 16, &value);
+	if (ret < 0)
+		return ret;
+
+	bytesin = strsep(strp, ":");
+	if (bytesin == NULL)
+		return -EINVAL;
+
+	ret = kstrtouint(bytesin, 16, &bytes);
+	if (ret < 0)
+		return ret;
+
+	if (bytes > DEBUGFS_CMD_MAX_WRITE_SIZE)
+		return -EINVAL;
+
+	wr->addr = (u16)addr;
+	wr->length = bytes;
+
+	for (i = 0; i < bytes; i++) {
+		wr->buf[i] = value & 0xff;
+		value >>= 8;
+	}
+
+	return 0;
+}
+
+
+static int idtptp_debugfs_help_show(struct seq_file *m, void *data)
+{
+	seq_printf(m, "%s\n", DEBUGFS_CMD_HELP);
+
+	return 0;
+}
+
+static int idtptp_debugfs_help_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, idtptp_debugfs_help_show, inode->i_private);
+}
+
+static const struct file_operations fops_help = {
+	.owner = THIS_MODULE,
+	.open = idtptp_debugfs_help_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int idtptp_debugfs_reg_show(struct seq_file *m, void *data)
+{
+	struct idtptp_debugfs *dbg = m->private;
+	struct idtptp_debugfs_data wrdata;
+	u16 regaddr = dbg->space.addr;
+	u8 buf[8] = {0};
+	int i, err;
+
+	wrdata.wr.buf = buf;
+	wrdata.wr.length = 8;
+
+	for (i = 0; i < dbg->space.length; i += 8, regaddr += 8) {
+		wrdata.wr.addr = regaddr;
+
+		err = dbg->handler(dbg->info, IDTPTP_DEBUGFS_READ_REG, &wrdata);
+
+		if (err)
+			return err;
+
+		seq_printf(m,
+			   "%04x %03x: %02x %02x %02x %02x %02x %02x %02x %02x\n",
+			   regaddr, i,
+			   buf[0], buf[1], buf[2], buf[3],
+			   buf[4], buf[5], buf[6], buf[7]);
+	}
+
+	return err;
+}
+
+static int idtptp_debugfs_reg_r_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, idtptp_debugfs_reg_show, inode->i_private);
+}
+
+static const struct file_operations fops_reg_r = {
+	.owner = THIS_MODULE,
+	.open = idtptp_debugfs_reg_r_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int idtptp_debugfs_parse(struct idtptp_debugfs *dbg,
+				char *cmdstr,
+				struct idtptp_debugfs_data *data)
+{
+	char **strp = &cmdstr;
+	int cmd, ret;
+	char *cmdin;
+
+	cmdin = strsep(strp, ":");
+	if (cmdin == NULL)
+		return -EINVAL;
+
+	cmd = idtptp_debugfs_parse_menu(cmdin, &cmdmenu);
+
+	switch (cmd) {
+	case IDTPTP_DEBUGFS_COMBOMODE:
+		ret = idtptp_debugfs_parse_combomode(cmdstr, data);
+		break;
+	case IDTPTP_DEBUGFS_WRITE_REG:
+		ret = idtptp_debugfs_parse_write(cmdstr, dbg->space, data);
+		break;
+	case IDTPTP_DEBUGFS_READ_REG:
+	default:
+		ret = -EINVAL;
+	}
+
+	if (ret < 0)
+		return ret;
+
+	return cmd;
+}
+
+static ssize_t idtptp_debugfs_cmd(struct file *file,
+				  const char __user *ptr,
+				  size_t len, loff_t *off)
+{
+	struct idtptp_debugfs *dbg = file->private_data;
+
+	struct idtptp_debugfs_data data;
+	char cmdstr[DEBUGFS_CMD_MAX_SIZE];
+	int cmd, err;
+	u8 wr_buf[DEBUGFS_CMD_MAX_WRITE_SIZE] = {0};
+
+	if (*off != 0)
+		return 0;
+
+	if (len > DEBUGFS_CMD_MAX_SIZE - 1)
+		len = DEBUGFS_CMD_MAX_SIZE - 1;
+
+	err = strncpy_from_user(cmdstr, ptr, len);
+	if (err < 0)
+		return err;
+	cmdstr[len] = '\0';
+
+	data.wr.buf = wr_buf;
+	data.wr.length = sizeof(wr_buf);
+
+	cmd = idtptp_debugfs_parse(dbg, cmdstr, &data);
+	if (cmd < 0)
+		return cmd;
+
+	err = dbg->handler(dbg->info, cmd, &data);
+	if (err < 0)
+		return err;
+
+	return len;
+}
+
+static const struct file_operations fops_cmd = {
+	.owner = THIS_MODULE,
+	.open = simple_open,
+	.write = idtptp_debugfs_cmd,
+	.llseek = noop_llseek,
+};
+
+idtptp_debugfs_handle *
+idtptp_debugfs_init(int index, struct ptp_clock_info *info,
+		    debugfs_cmd_handler handler,
+		    struct idtptp_debugfs_regs space)
+{
+	struct idtptp_debugfs *dbg;
+	char name[16];
+	int err = 0;
+
+	dbg = kzalloc(sizeof(struct idtptp_debugfs), GFP_KERNEL);
+	if (dbg == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	dbg->info = info;
+	dbg->handle = index;
+	dbg->handler = handler;
+	dbg->space = space;
+
+	snprintf(name, sizeof(name), "idtptp%u", index);
+
+	dbg->root = debugfs_create_dir(name, NULL);
+	if (!dbg->root) {
+		err = -ENOMEM;
+		goto ret;
+	}
+
+	dbg->help = debugfs_create_file("help", S_IFREG | S_IRUSR,
+					dbg->root, dbg, &fops_help);
+	if (!dbg->help) {
+		err = -ENOMEM;
+		goto ret;
+	}
+
+	dbg->regs = debugfs_create_file("regs", S_IFREG | S_IRUSR,
+					dbg->root, dbg, &fops_reg_r);
+	if (!dbg->regs) {
+		err = -ENOMEM;
+		goto ret;
+	}
+
+	dbg->cmd = debugfs_create_file("cmd", S_IFREG | S_IWUSR,
+					dbg->root, dbg, &fops_cmd);
+	if (!dbg->cmd) {
+		err = -ENOMEM;
+		goto ret;
+	}
+
+ret:
+	if (err < 0) {
+		idtptp_debugfs_exit(&dbg->handle);
+		return ERR_PTR(err);
+	}
+	return &dbg->handle;
+}
+EXPORT_SYMBOL(idtptp_debugfs_init);
+
+void idtptp_debugfs_exit(idtptp_debugfs_handle *handle)
+{
+	struct idtptp_debugfs *dbg =
+		container_of(handle, struct idtptp_debugfs, handle);
+
+	if (dbg == NULL)
+		return;
+
+	debugfs_remove(dbg->help);
+	debugfs_remove(dbg->regs);
+	debugfs_remove(dbg->cmd);
+	debugfs_remove(dbg->root);
+
+	kfree(dbg);
+}
+EXPORT_SYMBOL(idtptp_debugfs_exit);
diff --git a/drivers/ptp/ptp_idt_debugfs.h b/drivers/ptp/ptp_idt_debugfs.h
new file mode 100644
index 0000000..3c5e670
--- /dev/null
+++ b/drivers/ptp/ptp_idt_debugfs.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0+
+ *
+ * PTP debugfs interface for the IDT family of timing and
+ * synchronization devices.
+ *
+ * Copyright (C) 2019 Integrated Device Technology, Inc., a Renesas Company.
+ */
+#ifndef PTP_IDT_DEBUGFS_H
+#define PTP_IDT_DEBUGFS_H
+
+enum idtptp_debugfs_cmd {
+	IDTPTP_DEBUGFS_READ_REG = 0, /* read registers */
+	IDTPTP_DEBUGFS_WRITE_REG,    /* write registers */
+	IDTPTP_DEBUGFS_COMBOMODE,    /* set combo mode */
+	IDTPTP_DEBUGFS_MAX,
+};
+
+/**
+ * @brief Enumerated type listing DPLL combination modes
+ */
+enum idtdpll_combomode {
+	E_COMBOMODE_CURRENT = 0,   /* CURRENT/INSTANEOUS HOLDOVER OFFSET */
+	E_COMBOMODE_FASTAVG,       /* FAST AVERAGED HOLDOVER OFFSET */
+	E_COMBOMODE_SLOWAVG,       /* SLOW AVERAGED HOLDOVER OFFSET */
+	E_COMBOMODE_HOLDOVER,      /* HOLDER OVER OFFSET REGISTER VALUE USED */
+	E_COMBOMODE_MAX,
+};
+
+/* for register read/write */
+struct idtptp_debugfs_wr {
+	u16 addr;
+	u8 *buf;
+	u16 length;
+};
+
+/* device register space */
+struct idtptp_debugfs_regs {
+	u16 addr;
+	u16 length;
+};
+
+/* data passing to phc driver */
+struct idtptp_debugfs_data {
+	union {
+		enum idtdpll_combomode combomode;
+		struct idtptp_debugfs_wr wr;
+	};
+};
+
+struct ptp_clock_info;
+
+/* command handler provided by phc driver to handle idtptp_debugfs_cmd */
+typedef int (*debugfs_cmd_handler)(struct ptp_clock_info *info,
+				   enum idtptp_debugfs_cmd cmd,
+				   struct idtptp_debugfs_data *data);
+
+typedef int idtptp_debugfs_handle;
+
+/**
+ * idtptp_debugfs_init() - initialize idtptp debugfs interface
+ *
+ * @index   idtptp${index} as debugfs dir name
+ * @info    phc registered ptp_clock_info
+ * @handler handle idtptp_debugfs_cmd
+ * @space   device register space
+ *
+ * Returns a valid handle pointer on success or PTR_ERR on failure.
+ */
+idtptp_debugfs_handle *
+idtptp_debugfs_init(int index, struct ptp_clock_info *info,
+		    debugfs_cmd_handler handler,
+		    struct idtptp_debugfs_regs space);
+
+/**
+ * idtptp_debugfs_exit() - delete idtptp debugfs interface
+ *
+ * @handle  handle pointer from idtptp_debugfs_init
+ *
+ */
+void idtptp_debugfs_exit(idtptp_debugfs_handle *handle);
+
+#endif/* PTP_IDT_DEBUGFS_H */
+
