blob: eee70bad422d652e9cfa4110d89cadaa5aa6d6f7 [file]
/*
* QEMU model of the NXP FLEXCAN device.
*
* Copyright (c) 2025 Matyas Bobek <matyas.bobek@gmail.com>
*
* Based on CTU CAN FD emulation implemented by Jan Charvat.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef HW_CAN_FLEXCAN_H
#define HW_CAN_FLEXCAN_H
#include "net/can_emu.h"
#include "qom/object.h"
#include "hw/misc/imx_ccm.h"
#define FLEXCAN_FIFO_DEPTH 6
#define FLEXCAN_MAILBOX_COUNT 64
/**
* Definitions of structs FlexcanRegs and FlexcanRegsMessageBuffer were
* originally written for the Linux kernel by:
* Andrey Volkov <andrey@volkov.fr>
* Sascha Hauer <s.hauer@pengutronix.de>
* Marc Kleine-Budde <mkl@pengutronix.de>
* David Jander <david@protonic.nl>
* and they have agreed to license them under GPL-2.0-or-later.
*/
/* view of single message buffer registers */
typedef struct FlexcanRegsMessageBuffer {
uint32_t can_ctrl;
uint32_t can_id;
uint32_t data[2];
} FlexcanRegsMessageBuffer;
/* FlexCAN register in hw layout */
typedef struct FlexcanRegs {
uint32_t mcr; /* 0x00 */
uint32_t ctrl; /* 0x04 - not affected by soft reset */
uint32_t timer; /* 0x08 */
uint32_t tcr; /* 0x0C */
uint32_t rxmgmask; /* 0x10 - not affected by soft reset */
uint32_t rx14mask; /* 0x14 - not affected by soft reset */
uint32_t rx15mask; /* 0x18 - not affected by soft reset */
uint32_t ecr; /* 0x1C */
uint32_t esr; /* 0x20 */
uint32_t imask2; /* 0x24 */
uint32_t imask1; /* 0x28 */
uint32_t iflag2; /* 0x2C */
uint32_t iflag1; /* 0x30 */
union { /* 0x34 */
uint32_t gfwr_mx28; /* MX28, MX53 */
uint32_t ctrl2; /* MX6, VF610 - not affected by soft reset */
};
uint32_t esr2; /* 0x38 */
uint32_t imeur; /* 0x3C, unused */
uint32_t lrfr; /* 0x40, unused */
uint32_t crcr; /* 0x44 */
uint32_t rxfgmask; /* 0x48 */
uint32_t rxfir; /* 0x4C - not affected by soft reset */
uint32_t cbt; /* 0x50, unused - not affected by soft reset */
uint32_t _reserved2; /* 0x54 */
uint32_t dbg1; /* 0x58, unused */
uint32_t dbg2; /* 0x5C, unused */
uint32_t _reserved3[8]; /* 0x60 */
/* 0x80 - not affected by soft reset */
FlexcanRegsMessageBuffer mbs[FLEXCAN_MAILBOX_COUNT];
uint32_t _reserved4[256]; /* 0x480 */
uint32_t rximr[64]; /* 0x880 - not affected by soft reset */
uint32_t _reserved5[24]; /* 0x980 */
uint32_t gfwr_mx6; /* 0x9E0 - MX6 */
/* the rest is unused except for SMB */
uint32_t _reserved6[39]; /* 0x9E4 */
uint32_t _rxfir[6]; /* 0xA80 */
uint32_t _reserved8[2]; /* 0xA98 */
uint32_t _rxmgmask; /* 0xAA0 */
uint32_t _rxfgmask; /* 0xAA4 */
uint32_t _rx14mask; /* 0xAA8 */
uint32_t _rx15mask; /* 0xAAC */
uint32_t tx_smb[4]; /* 0xAB0 */
FlexcanRegsMessageBuffer rx_smb0; /* 0xAC0, used for SMB emulation */
uint32_t rx_smb1[4]; /* 0xAD0 */
uint32_t mecr; /* 0xAE0 */
uint32_t erriar; /* 0xAE4 */
uint32_t erridpr; /* 0xAE8 */
uint32_t errippr; /* 0xAEC */
uint32_t rerrar; /* 0xAF0 */
uint32_t rerrdr; /* 0xAF4 */
uint32_t rerrsynr; /* 0xAF8 */
uint32_t errsr; /* 0xAFC */
uint32_t _reserved7[64]; /* 0xB00 */
uint32_t fdctrl; /* 0xC00 - not affected by soft reset */
uint32_t fdcbt; /* 0xC04 - not affected by soft reset */
uint32_t fdcrc; /* 0xC08 */
uint32_t _reserved9[199]; /* 0xC0C */
uint32_t tx_smb_fd[18]; /* 0xF28 */
uint32_t rx_smb0_fd[18]; /* 0xF70 */
uint32_t rx_smb1_fd[18]; /* 0xFB8 */
} FlexcanRegs;
typedef struct FlexcanState {
SysBusDevice parent_obj;
MemoryRegion iomem;
IMXCCMState *ccm;
qemu_irq irq;
CanBusState *canbus;
CanBusClientState bus_client;
union {
FlexcanRegs regs;
uint32_t regs_raw[sizeof(FlexcanRegs) / 4];
};
int64_t timer_start;
uint64_t last_rx_timer_cycles;
int32_t locked_mbidx;
int32_t smb_target_mbidx;
uint32_t timer_freq;
} FlexcanState;
#define TYPE_CAN_FLEXCAN "flexcan"
OBJECT_DECLARE_SIMPLE_TYPE(FlexcanState, CAN_FLEXCAN);
#define TYPE_CAN_FLEXCAN2 "flexcan2"
#define TYPE_CAN_FLEXCAN3 "flexcan3"
#endif