// SPDX-License-Identifier: GPL-2.0
/* TI K3 AM65x Common Platform Time Sync
*
* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
*
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/if_vlan.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/net_tstamp.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/ptp_classify.h>
#include <linux/ptp_clock_kernel.h>
#include "am65-cpts.h"
struct am65_genf_regs {
u32 comp_lo; /* Comparison Low Value 0:31 */
u32 comp_hi; /* Comparison High Value 32:63 */
u32 control; /* control */
u32 length; /* Length */
u32 ppm_low; /* PPM Load Low Value 0:31 */
u32 ppm_hi; /* PPM Load High Value 32:63 */
u32 ts_nudge; /* Nudge value */
} __aligned(32) __packed;
#define AM65_CPTS_GENF_MAX_NUM 9
#define AM65_CPTS_ESTF_MAX_NUM 8
struct am65_cpts_regs {
u32 idver; /* Identification and version */
u32 control; /* Time sync control */
u32 rftclk_sel; /* Reference Clock Select Register */
u32 ts_push; /* Time stamp event push */
u32 ts_load_val_lo; /* Time Stamp Load Low Value 0:31 */
u32 ts_load_en; /* Time stamp load enable */
u32 ts_comp_lo; /* Time Stamp Comparison Low Value 0:31 */
u32 ts_comp_length; /* Time Stamp Comparison Length */
u32 intstat_raw; /* Time sync interrupt status raw */
u32 intstat_masked; /* Time sync interrupt status masked */
u32 int_enable; /* Time sync interrupt enable */
u32 ts_comp_nudge; /* Time Stamp Comparison Nudge Value */
u32 event_pop; /* Event interrupt pop */
u32 event_0; /* Event Time Stamp lo 0:31 */
u32 event_1; /* Event Type Fields */
u32 event_2; /* Event Type Fields domain */
u32 event_3; /* Event Time Stamp hi 32:63 */
u32 ts_load_val_hi; /* Time Stamp Load High Value 32:63 */
u32 ts_comp_hi; /* Time Stamp Comparison High Value 32:63 */
u32 ts_add_val; /* Time Stamp Add value */
u32 ts_ppm_low; /* Time Stamp PPM Load Low Value 0:31 */
u32 ts_ppm_hi; /* Time Stamp PPM Load High Value 32:63 */
u32 ts_nudge; /* Time Stamp Nudge value */
u32 reserv[33];
struct am65_genf_regs genf[AM65_CPTS_GENF_MAX_NUM];
struct am65_genf_regs estf[AM65_CPTS_ESTF_MAX_NUM];
};
/* CONTROL_REG */
#define AM65_CPTS_CONTROL_EN BIT(0)
#define AM65_CPTS_CONTROL_INT_TEST BIT(1)
#define AM65_CPTS_CONTROL_TS_COMP_POLARITY BIT(2)
#define AM65_CPTS_CONTROL_TSTAMP_EN BIT(3)
#define AM65_CPTS_CONTROL_SEQUENCE_EN BIT(4)
#define AM65_CPTS_CONTROL_64MODE BIT(5)
#define AM65_CPTS_CONTROL_TS_COMP_TOG BIT(6)
#define AM65_CPTS_CONTROL_TS_PPM_DIR BIT(7)
#define AM65_CPTS_CONTROL_HW1_TS_PUSH_EN BIT(8)
#define AM65_CPTS_CONTROL_HW2_TS_PUSH_EN BIT(9)
#define AM65_CPTS_CONTROL_HW3_TS_PUSH_EN BIT(10)
#define AM65_CPTS_CONTROL_HW4_TS_PUSH_EN BIT(11)
#define AM65_CPTS_CONTROL_HW5_TS_PUSH_EN BIT(12)
#define AM65_CPTS_CONTROL_HW6_TS_PUSH_EN BIT(13)
#define AM65_CPTS_CONTROL_HW7_TS_PUSH_EN BIT(14)
#define AM65_CPTS_CONTROL_HW8_TS_PUSH_EN BIT(15)
#define AM65_CPTS_CONTROL_HW1_TS_PUSH_OFFSET (8)
#define AM65_CPTS_CONTROL_TX_GENF_CLR_EN BIT(17)
#define AM65_CPTS_CONTROL_TS_SYNC_SEL_MASK (0xF)
#define AM65_CPTS_CONTROL_TS_SYNC_SEL_SHIFT (28)
/* RFTCLK_SEL_REG */
#define AM65_CPTS_RFTCLK_SEL_MASK (0x1F)
/* TS_PUSH_REG */
#define AM65_CPTS_TS_PUSH BIT(0)
/* TS_LOAD_EN_REG */
#define AM65_CPTS_TS_LOAD_EN BIT(0)
/* INTSTAT_RAW_REG */
#define AM65_CPTS_INTSTAT_RAW_TS_PEND BIT(0)
/* INTSTAT_MASKED_REG */
#define AM65_CPTS_INTSTAT_MASKED_TS_PEND BIT(0)
/* INT_ENABLE_REG */
#define AM65_CPTS_INT_ENABLE_TS_PEND_EN BIT(0)
/* TS_COMP_NUDGE_REG */
#define AM65_CPTS_TS_COMP_NUDGE_MASK (0xFF)
/* EVENT_POP_REG */
#define AM65_CPTS_EVENT_POP BIT(0)
/* EVENT_1_REG */
#define AM65_CPTS_EVENT_1_SEQUENCE_ID_MASK GENMASK(15, 0)
#define AM65_CPTS_EVENT_1_MESSAGE_TYPE_MASK GENMASK(19, 16)
#define AM65_CPTS_EVENT_1_MESSAGE_TYPE_SHIFT (16)
#define AM65_CPTS_EVENT_1_EVENT_TYPE_MASK GENMASK(23, 20)
#define AM65_CPTS_EVENT_1_EVENT_TYPE_SHIFT (20)
#define AM65_CPTS_EVENT_1_PORT_NUMBER_MASK GENMASK(28, 24)
#define AM65_CPTS_EVENT_1_PORT_NUMBER_SHIFT (24)
/* EVENT_2_REG */
#define AM65_CPTS_EVENT_2_REG_DOMAIN_MASK (0xFF)
#define AM65_CPTS_EVENT_2_REG_DOMAIN_SHIFT (0)
enum {
AM65_CPTS_EV_PUSH, /* Time Stamp Push Event */
AM65_CPTS_EV_ROLL, /* Time Stamp Rollover Event */
AM65_CPTS_EV_HALF, /* Time Stamp Half Rollover Event */
AM65_CPTS_EV_HW, /* Hardware Time Stamp Push Event */
AM65_CPTS_EV_RX, /* Ethernet Receive Event */
AM65_CPTS_EV_TX, /* Ethernet Transmit Event */
AM65_CPTS_EV_TS_COMP, /* Time Stamp Compare Event */
AM65_CPTS_EV_HOST, /* Host Transmit Event */
};
struct am65_cpts_event {
struct list_head list;
unsigned long tmo;
u32 event1;
u32 event2;
u64 timestamp;
};
#define AM65_CPTS_FIFO_DEPTH (16)
#define AM65_CPTS_MAX_EVENTS (32)
#define AM65_CPTS_EVENT_RX_TX_TIMEOUT (20)