brintos

brintos / linux-shallow public Read only

0
0
Text · 9.4 KiB · 6b7ebd8 Raw
359 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/* Copyright (C) 2015 - 2016 Thomas Körper, esd electronic system design gmbh3 * Copyright (C) 2017 - 2023 Stefan Mätje, esd electronics gmbh4 */5 6#include <linux/bits.h>7#include <linux/can/dev.h>8#include <linux/kernel.h>9#include <linux/netdevice.h>10#include <linux/units.h>11 12#define ACC_TS_FREQ_80MHZ (80 * HZ_PER_MHZ)13#define ACC_I2C_ADDON_DETECT_DELAY_MS 1014 15/* esdACC Overview Module */16#define ACC_OV_OF_PROBE	0x000017#define ACC_OV_OF_VERSION 0x000418#define ACC_OV_OF_INFO 0x000819#define ACC_OV_OF_CANCORE_FREQ 0x000c20#define ACC_OV_OF_TS_FREQ_LO 0x001021#define ACC_OV_OF_TS_FREQ_HI 0x001422#define ACC_OV_OF_IRQ_STATUS_CORES 0x001823#define ACC_OV_OF_TS_CURR_LO 0x001c24#define ACC_OV_OF_TS_CURR_HI 0x002025#define ACC_OV_OF_IRQ_STATUS 0x002826#define ACC_OV_OF_MODE 0x002c27#define ACC_OV_OF_BM_IRQ_COUNTER 0x007028#define ACC_OV_OF_BM_IRQ_MASK 0x007429#define ACC_OV_OF_MSI_DATA 0x008030#define ACC_OV_OF_MSI_ADDRESSOFFSET 0x008431 32/* Feature flags are contained in the upper 16 bit of the version33 * register at ACC_OV_OF_VERSION but only used with these masks after34 * extraction into an extra variable => (xx - 16).35 */36#define ACC_OV_REG_FEAT_MASK_CANFD BIT(27 - 16)37#define ACC_OV_REG_FEAT_MASK_NEW_PSC BIT(28 - 16)38#define ACC_OV_REG_FEAT_MASK_DAR BIT(30 - 16)39 40#define ACC_OV_REG_MODE_MASK_ENDIAN_LITTLE BIT(0)41#define ACC_OV_REG_MODE_MASK_BM_ENABLE BIT(1)42#define ACC_OV_REG_MODE_MASK_MODE_LED BIT(2)43#define ACC_OV_REG_MODE_MASK_TIMER_ENABLE BIT(4)44#define ACC_OV_REG_MODE_MASK_TIMER_ONE_SHOT BIT(5)45#define ACC_OV_REG_MODE_MASK_TIMER_ABSOLUTE BIT(6)46#define ACC_OV_REG_MODE_MASK_TIMER GENMASK(6, 4)47#define ACC_OV_REG_MODE_MASK_TS_SRC GENMASK(8, 7)48#define ACC_OV_REG_MODE_MASK_I2C_ENABLE BIT(11)49#define ACC_OV_REG_MODE_MASK_MSI_ENABLE BIT(14)50#define ACC_OV_REG_MODE_MASK_NEW_PSC_ENABLE BIT(15)51#define ACC_OV_REG_MODE_MASK_FPGA_RESET BIT(31)52 53/* esdACC CAN Core Module */54#define ACC_CORE_OF_CTRL 0x000055#define ACC_CORE_OF_STATUS_IRQ 0x000856#define ACC_CORE_OF_BRP	0x000c57#define ACC_CORE_OF_BTR	0x001058#define ACC_CORE_OF_FBTR 0x001459#define ACC_CORE_OF_STATUS 0x003060#define ACC_CORE_OF_TXFIFO_CONFIG 0x004861#define ACC_CORE_OF_TXFIFO_STATUS 0x004c62#define ACC_CORE_OF_TX_STATUS_IRQ 0x005063#define ACC_CORE_OF_TX_ABORT_MASK 0x005464#define ACC_CORE_OF_BM_IRQ_COUNTER 0x007065#define ACC_CORE_OF_TXFIFO_ID 0x00c066#define ACC_CORE_OF_TXFIFO_DLC 0x00c467#define ACC_CORE_OF_TXFIFO_DATA_0 0x00c868#define ACC_CORE_OF_TXFIFO_DATA_1 0x00cc69 70/* CTRL register layout */71#define ACC_REG_CTRL_MASK_RESETMODE BIT(0)72#define ACC_REG_CTRL_MASK_LOM BIT(1)73#define ACC_REG_CTRL_MASK_STM BIT(2)74#define ACC_REG_CTRL_MASK_TRANSEN BIT(5)75#define ACC_REG_CTRL_MASK_TS BIT(6)76#define ACC_REG_CTRL_MASK_SCHEDULE BIT(7)77 78#define ACC_REG_CTRL_MASK_IE_RXTX BIT(8)79#define ACC_REG_CTRL_MASK_IE_TXERROR BIT(9)80#define ACC_REG_CTRL_MASK_IE_ERRWARN BIT(10)81#define ACC_REG_CTRL_MASK_IE_OVERRUN BIT(11)82#define ACC_REG_CTRL_MASK_IE_TSI BIT(12)83#define ACC_REG_CTRL_MASK_IE_ERRPASS BIT(13)84#define ACC_REG_CTRL_MASK_IE_ALI BIT(14)85#define ACC_REG_CTRL_MASK_IE_BUSERR BIT(15)86 87/* BRP and BTR register layout for CAN-Classic version */88#define ACC_REG_BRP_CL_MASK_BRP GENMASK(8, 0)89#define ACC_REG_BTR_CL_MASK_TSEG1 GENMASK(3, 0)90#define ACC_REG_BTR_CL_MASK_TSEG2 GENMASK(18, 16)91#define ACC_REG_BTR_CL_MASK_SJW GENMASK(25, 24)92 93/* BRP and BTR register layout for CAN-FD version */94#define ACC_REG_BRP_FD_MASK_BRP GENMASK(7, 0)95#define ACC_REG_BTR_FD_MASK_TSEG1 GENMASK(7, 0)96#define ACC_REG_BTR_FD_MASK_TSEG2 GENMASK(22, 16)97#define ACC_REG_BTR_FD_MASK_SJW GENMASK(30, 24)98 99/* 256 BM_MSGs of 32 byte size */100#define ACC_CORE_DMAMSG_SIZE 32U101#define ACC_CORE_DMABUF_SIZE (256U * ACC_CORE_DMAMSG_SIZE)102 103enum acc_bmmsg_id {104	BM_MSG_ID_RXTXDONE = 0x01,105	BM_MSG_ID_TXABORT = 0x02,106	BM_MSG_ID_OVERRUN = 0x03,107	BM_MSG_ID_BUSERR = 0x04,108	BM_MSG_ID_ERRPASSIVE = 0x05,109	BM_MSG_ID_ERRWARN = 0x06,110	BM_MSG_ID_TIMESLICE = 0x07,111	BM_MSG_ID_HWTIMER = 0x08,112	BM_MSG_ID_HOTPLUG = 0x09,113};114 115/* The struct acc_bmmsg_* structure declarations that follow here provide116 * access to the ring buffer of bus master messages maintained by the FPGA117 * bus master engine. All bus master messages have the same size of118 * ACC_CORE_DMAMSG_SIZE and a minimum alignment of ACC_CORE_DMAMSG_SIZE in119 * memory.120 *121 * All structure members are natural aligned. Therefore we should not need122 * a __packed attribute. All struct acc_bmmsg_* declarations have at least123 * reserved* members to fill the structure to the full ACC_CORE_DMAMSG_SIZE.124 *125 * A failure of this property due padding will be detected at compile time126 * by static_assert(sizeof(union acc_bmmsg) == ACC_CORE_DMAMSG_SIZE).127 */128 129struct acc_bmmsg_rxtxdone {130	u8 msg_id;131	u8 txfifo_level;132	u8 reserved1[2];133	u8 txtsfifo_level;134	u8 reserved2[3];135	u32 id;136	struct {137		u8 len;138		u8 txdfifo_idx;139		u8 zeroes8;140		u8 reserved;141	} acc_dlc;142	u8 data[CAN_MAX_DLEN];143	/* Time stamps in struct acc_ov::timestamp_frequency ticks. */144	u64 ts;145};146 147struct acc_bmmsg_txabort {148	u8 msg_id;149	u8 txfifo_level;150	u16 abort_mask;151	u8 txtsfifo_level;152	u8 reserved2[1];153	u16 abort_mask_txts;154	u64 ts;155	u32 reserved3[4];156};157 158struct acc_bmmsg_overrun {159	u8 msg_id;160	u8 txfifo_level;161	u8 lost_cnt;162	u8 reserved1;163	u8 txtsfifo_level;164	u8 reserved2[3];165	u64 ts;166	u32 reserved3[4];167};168 169struct acc_bmmsg_buserr {170	u8 msg_id;171	u8 txfifo_level;172	u8 ecc;173	u8 reserved1;174	u8 txtsfifo_level;175	u8 reserved2[3];176	u64 ts;177	u32 reg_status;178	u32 reg_btr;179	u32 reserved3[2];180};181 182struct acc_bmmsg_errstatechange {183	u8 msg_id;184	u8 txfifo_level;185	u8 reserved1[2];186	u8 txtsfifo_level;187	u8 reserved2[3];188	u64 ts;189	u32 reg_status;190	u32 reserved3[3];191};192 193struct acc_bmmsg_timeslice {194	u8 msg_id;195	u8 txfifo_level;196	u8 reserved1[2];197	u8 txtsfifo_level;198	u8 reserved2[3];199	u64 ts;200	u32 reserved3[4];201};202 203struct acc_bmmsg_hwtimer {204	u8 msg_id;205	u8 reserved1[3];206	u32 reserved2[1];207	u64 timer;208	u32 reserved3[4];209};210 211struct acc_bmmsg_hotplug {212	u8 msg_id;213	u8 reserved1[3];214	u32 reserved2[7];215};216 217union acc_bmmsg {218	u8 msg_id;219	struct acc_bmmsg_rxtxdone rxtxdone;220	struct acc_bmmsg_txabort txabort;221	struct acc_bmmsg_overrun overrun;222	struct acc_bmmsg_buserr buserr;223	struct acc_bmmsg_errstatechange errstatechange;224	struct acc_bmmsg_timeslice timeslice;225	struct acc_bmmsg_hwtimer hwtimer;226};227 228/* Check size of union acc_bmmsg to be of expected size. */229static_assert(sizeof(union acc_bmmsg) == ACC_CORE_DMAMSG_SIZE);230 231struct acc_bmfifo {232	const union acc_bmmsg *messages;233	/* irq_cnt points to an u32 value where the esdACC FPGA deposits234	 * the bm_fifo head index in coherent DMA memory. Only bits 7..0235	 * are valid. Use READ_ONCE() to access this memory location.236	 */237	const u32 *irq_cnt;238	u32 local_irq_cnt;239	u32 msg_fifo_tail;240};241 242struct acc_core {243	void __iomem *addr;244	struct net_device *netdev;245	struct acc_bmfifo bmfifo;246	u8 tx_fifo_size;247	u8 tx_fifo_head;248	u8 tx_fifo_tail;249};250 251struct acc_ov {252	void __iomem *addr;253	struct acc_bmfifo bmfifo;254	u32 timestamp_frequency;255	u32 core_frequency;256	u16 version;257	u16 features;258	u8 total_cores;259	u8 active_cores;260};261 262struct acc_net_priv {263	struct can_priv can; /* must be the first member! */264	struct acc_core *core;265	struct acc_ov *ov;266};267 268static inline u32 acc_read32(struct acc_core *core, unsigned short offs)269{270	return ioread32be(core->addr + offs);271}272 273static inline void acc_write32(struct acc_core *core,274			       unsigned short offs, u32 v)275{276	iowrite32be(v, core->addr + offs);277}278 279static inline void acc_write32_noswap(struct acc_core *core,280				      unsigned short offs, u32 v)281{282	iowrite32(v, core->addr + offs);283}284 285static inline void acc_set_bits(struct acc_core *core,286				unsigned short offs, u32 mask)287{288	u32 v = acc_read32(core, offs);289 290	v |= mask;291	acc_write32(core, offs, v);292}293 294static inline void acc_clear_bits(struct acc_core *core,295				  unsigned short offs, u32 mask)296{297	u32 v = acc_read32(core, offs);298 299	v &= ~mask;300	acc_write32(core, offs, v);301}302 303static inline int acc_resetmode_entered(struct acc_core *core)304{305	u32 ctrl = acc_read32(core, ACC_CORE_OF_CTRL);306 307	return (ctrl & ACC_REG_CTRL_MASK_RESETMODE) != 0;308}309 310static inline u32 acc_ov_read32(struct acc_ov *ov, unsigned short offs)311{312	return ioread32be(ov->addr + offs);313}314 315static inline void acc_ov_write32(struct acc_ov *ov,316				  unsigned short offs, u32 v)317{318	iowrite32be(v, ov->addr + offs);319}320 321static inline void acc_ov_set_bits(struct acc_ov *ov,322				   unsigned short offs, u32 b)323{324	u32 v = acc_ov_read32(ov, offs);325 326	v |= b;327	acc_ov_write32(ov, offs, v);328}329 330static inline void acc_ov_clear_bits(struct acc_ov *ov,331				     unsigned short offs, u32 b)332{333	u32 v = acc_ov_read32(ov, offs);334 335	v &= ~b;336	acc_ov_write32(ov, offs, v);337}338 339static inline void acc_reset_fpga(struct acc_ov *ov)340{341	acc_ov_write32(ov, ACC_OV_OF_MODE, ACC_OV_REG_MODE_MASK_FPGA_RESET);342 343	/* (Re-)start and wait for completion of addon detection on the I^2C bus */344	acc_ov_set_bits(ov, ACC_OV_OF_MODE, ACC_OV_REG_MODE_MASK_I2C_ENABLE);345	mdelay(ACC_I2C_ADDON_DETECT_DELAY_MS);346}347 348void acc_init_ov(struct acc_ov *ov, struct device *dev);349void acc_init_bm_ptr(struct acc_ov *ov, struct acc_core *cores,350		     const void *mem);351int acc_open(struct net_device *netdev);352int acc_close(struct net_device *netdev);353netdev_tx_t acc_start_xmit(struct sk_buff *skb, struct net_device *netdev);354int acc_get_berr_counter(const struct net_device *netdev,355			 struct can_berr_counter *bec);356int acc_set_mode(struct net_device *netdev, enum can_mode mode);357int acc_set_bittiming(struct net_device *netdev);358irqreturn_t acc_card_interrupt(struct acc_ov *ov, struct acc_core *cores);359