162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci * flexcan.c - FLEXCAN CAN controller driver 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 2005-2006 Varma Electronics Oy 562306a36Sopenharmony_ci * Copyright (c) 2009 Sascha Hauer, Pengutronix 662306a36Sopenharmony_ci * Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de> 762306a36Sopenharmony_ci * Copyright (c) 2014 David Jander, Protonic Holland 862306a36Sopenharmony_ci * Copyright (C) 2022 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com> 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Based on code originally by Andrey Volkov <avolkov@varma-el.com> 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#ifndef _FLEXCAN_H 1562306a36Sopenharmony_ci#define _FLEXCAN_H 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <linux/can/rx-offload.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* FLEXCAN hardware feature flags 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * Below is some version info we got: 2262306a36Sopenharmony_ci * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode MB 2362306a36Sopenharmony_ci * Filter? connected? Passive detection ption in MB Supported? 2462306a36Sopenharmony_ci * MCF5441X FlexCAN2 ? no yes no no no no 16 2562306a36Sopenharmony_ci * MX25 FlexCAN2 03.00.00.00 no no no no no no 64 2662306a36Sopenharmony_ci * MX28 FlexCAN2 03.00.04.00 yes yes no no no no 64 2762306a36Sopenharmony_ci * MX35 FlexCAN2 03.00.00.00 no no no no no no 64 2862306a36Sopenharmony_ci * MX53 FlexCAN2 03.00.00.00 yes no no no no no 64 2962306a36Sopenharmony_ci * MX6s FlexCAN3 10.00.12.00 yes yes no no yes no 64 3062306a36Sopenharmony_ci * MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes 64 3162306a36Sopenharmony_ci * MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes 64 3262306a36Sopenharmony_ci * VF610 FlexCAN3 ? no yes no yes yes? no 64 3362306a36Sopenharmony_ci * LS1021A FlexCAN2 03.00.04.00 no yes no no yes no 64 3462306a36Sopenharmony_ci * LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes 64 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. 3762306a36Sopenharmony_ci */ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* [TR]WRN_INT not connected */ 4062306a36Sopenharmony_ci#define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) 4162306a36Sopenharmony_ci /* Disable RX FIFO Global mask */ 4262306a36Sopenharmony_ci#define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) 4362306a36Sopenharmony_ci/* Enable EACEN and RRS bit in ctrl2 */ 4462306a36Sopenharmony_ci#define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) 4562306a36Sopenharmony_ci/* Disable non-correctable errors interrupt and freeze mode */ 4662306a36Sopenharmony_ci#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) 4762306a36Sopenharmony_ci/* Use mailboxes (not FIFO) for RX path */ 4862306a36Sopenharmony_ci#define FLEXCAN_QUIRK_USE_RX_MAILBOX BIT(5) 4962306a36Sopenharmony_ci/* No interrupt for error passive */ 5062306a36Sopenharmony_ci#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) 5162306a36Sopenharmony_ci/* default to BE register access */ 5262306a36Sopenharmony_ci#define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) 5362306a36Sopenharmony_ci/* Setup stop mode with GPR to support wakeup */ 5462306a36Sopenharmony_ci#define FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR BIT(8) 5562306a36Sopenharmony_ci/* Support CAN-FD mode */ 5662306a36Sopenharmony_ci#define FLEXCAN_QUIRK_SUPPORT_FD BIT(9) 5762306a36Sopenharmony_ci/* support memory detection and correction */ 5862306a36Sopenharmony_ci#define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10) 5962306a36Sopenharmony_ci/* Setup stop mode with SCU firmware to support wakeup */ 6062306a36Sopenharmony_ci#define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW BIT(11) 6162306a36Sopenharmony_ci/* Setup 3 separate interrupts, main, boff and err */ 6262306a36Sopenharmony_ci#define FLEXCAN_QUIRK_NR_IRQ_3 BIT(12) 6362306a36Sopenharmony_ci/* Setup 16 mailboxes */ 6462306a36Sopenharmony_ci#define FLEXCAN_QUIRK_NR_MB_16 BIT(13) 6562306a36Sopenharmony_ci/* Device supports RX via mailboxes */ 6662306a36Sopenharmony_ci#define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX BIT(14) 6762306a36Sopenharmony_ci/* Device supports RTR reception via mailboxes */ 6862306a36Sopenharmony_ci#define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR BIT(15) 6962306a36Sopenharmony_ci/* Device supports RX via FIFO */ 7062306a36Sopenharmony_ci#define FLEXCAN_QUIRK_SUPPORT_RX_FIFO BIT(16) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistruct flexcan_devtype_data { 7362306a36Sopenharmony_ci u32 quirks; /* quirks needed for different IP cores */ 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistruct flexcan_stop_mode { 7762306a36Sopenharmony_ci struct regmap *gpr; 7862306a36Sopenharmony_ci u8 req_gpr; 7962306a36Sopenharmony_ci u8 req_bit; 8062306a36Sopenharmony_ci}; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistruct flexcan_priv { 8362306a36Sopenharmony_ci struct can_priv can; 8462306a36Sopenharmony_ci struct can_rx_offload offload; 8562306a36Sopenharmony_ci struct device *dev; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci struct flexcan_regs __iomem *regs; 8862306a36Sopenharmony_ci struct flexcan_mb __iomem *tx_mb; 8962306a36Sopenharmony_ci struct flexcan_mb __iomem *tx_mb_reserved; 9062306a36Sopenharmony_ci u8 tx_mb_idx; 9162306a36Sopenharmony_ci u8 mb_count; 9262306a36Sopenharmony_ci u8 mb_size; 9362306a36Sopenharmony_ci u8 clk_src; /* clock source of CAN Protocol Engine */ 9462306a36Sopenharmony_ci u8 scu_idx; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci u64 rx_mask; 9762306a36Sopenharmony_ci u64 tx_mask; 9862306a36Sopenharmony_ci u32 reg_ctrl_default; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci struct clk *clk_ipg; 10162306a36Sopenharmony_ci struct clk *clk_per; 10262306a36Sopenharmony_ci struct flexcan_devtype_data devtype_data; 10362306a36Sopenharmony_ci struct regulator *reg_xceiver; 10462306a36Sopenharmony_ci struct flexcan_stop_mode stm; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci int irq_boff; 10762306a36Sopenharmony_ci int irq_err; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci /* IPC handle when setup stop mode by System Controller firmware(scfw) */ 11062306a36Sopenharmony_ci struct imx_sc_ipc *sc_ipc_handle; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci /* Read and Write APIs */ 11362306a36Sopenharmony_ci u32 (*read)(void __iomem *addr); 11462306a36Sopenharmony_ci void (*write)(u32 val, void __iomem *addr); 11562306a36Sopenharmony_ci}; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ciextern const struct ethtool_ops flexcan_ethtool_ops; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistatic inline bool 12062306a36Sopenharmony_ciflexcan_supports_rx_mailbox(const struct flexcan_priv *priv) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci const u32 quirks = priv->devtype_data.quirks; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci return quirks & FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX; 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistatic inline bool 12862306a36Sopenharmony_ciflexcan_supports_rx_mailbox_rtr(const struct flexcan_priv *priv) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci const u32 quirks = priv->devtype_data.quirks; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci return (quirks & (FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX | 13362306a36Sopenharmony_ci FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR)) == 13462306a36Sopenharmony_ci (FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX | 13562306a36Sopenharmony_ci FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR); 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_cistatic inline bool 13962306a36Sopenharmony_ciflexcan_supports_rx_fifo(const struct flexcan_priv *priv) 14062306a36Sopenharmony_ci{ 14162306a36Sopenharmony_ci const u32 quirks = priv->devtype_data.quirks; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci return quirks & FLEXCAN_QUIRK_SUPPORT_RX_FIFO; 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistatic inline bool 14762306a36Sopenharmony_ciflexcan_active_rx_rtr(const struct flexcan_priv *priv) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci const u32 quirks = priv->devtype_data.quirks; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci if (quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) { 15262306a36Sopenharmony_ci if (quirks & FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR) 15362306a36Sopenharmony_ci return true; 15462306a36Sopenharmony_ci } else { 15562306a36Sopenharmony_ci /* RX-FIFO is always RTR capable */ 15662306a36Sopenharmony_ci return true; 15762306a36Sopenharmony_ci } 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci return false; 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci#endif /* _FLEXCAN_H */ 164