/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SH_SCI_COMMON_H__#define __SH_SCI_COMMON_H__ #include <linux/serial_core.h> /* Private port IDs */enum SCI_PORT_TYPE { RSCI_PORT_SCIF16 = BIT(7) | 0, RSCI_PORT_SCIF32 = BIT(7) | 1, RSCI_PORT_SCIF32_SINGLE_TCLK = BIT(7) | 2,}; enum SCI_CLKS { SCI_FCK, /* Functional Clock */ SCI_SCK, /* Optional External Clock */ SCI_BRG_INT, /* Optional BRG Internal Clock Source */ SCI_SCIF_CLK, /* Optional BRG External Clock Source */ SCI_FCK_DIV4, /* Optional Functional Clock frequency-divided by 4 */ SCI_FCK_DIV16, /* Optional Functional Clock frequency-divided by 16 */ SCI_FCK_DIV64, /* Optional Functional Clock frequency-divided by 64 */ SCI_NUM_CLKS}; /* Offsets into the sci_port->irqs array */enum { SCIx_ERI_IRQ, SCIx_RXI_IRQ, SCIx_TXI_IRQ, SCIx_BRI_IRQ, SCIx_DRI_IRQ, SCIx_TEI_IRQ, SCIx_NR_IRQS, SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */}; /* Bit x set means sampling rate x + 1 is supported */#define SCI_SR(x) BIT((x) - 1)#define SCI_SR_RANGE(x, y) GENMASK((y) - 1, (x) - 1) void sci_release_port(struct uart_port *port);int sci_request_port(struct uart_port *port);void sci_config_port(struct uart_port *port, int flags);int sci_verify_port(struct uart_port *port, struct serial_struct *ser);void sci_pm(struct uart_port *port, unsigned int state, unsigned int oldstate); struct plat_sci_reg { u8 offset; u8 size;}; struct sci_port_params_bits { unsigned int rxtx_enable; unsigned int te_clear; unsigned int poll_sent_bits;}; struct sci_common_regs { unsigned int status; unsigned int control;}; /* The actual number of needed registers. This is used by sci only */#define SCI_NR_REGS 20 struct sci_port_params { const struct plat_sci_reg regs[SCI_NR_REGS]; const struct sci_common_regs *common_regs; const struct sci_port_params_bits *param_bits; unsigned int fifosize; unsigned int overrun_reg; unsigned int overrun_mask; unsigned int sampling_rate_mask; unsigned int error_mask; unsigned int error_clear;}; struct sci_port_ops { u32 (*read_reg)(struct uart_port *port, int reg); void (*write_reg)(struct uart_port *port, int reg, int value); void (*clear_SCxSR)(struct uart_port *port, unsigned int mask); void (*transmit_chars)(struct uart_port *port); void (*receive_chars)(struct uart_port *port); void (*poll_put_char)(struct uart_port *port, unsigned char c); int (*set_rtrg)(struct uart_port *port, int rx_trig); int (*rtrg_enabled)(struct uart_port *port); void (*shutdown_complete)(struct uart_port *port); void (*prepare_console_write)(struct uart_port *port, u32 ctrl); void (*finish_console_write)(struct uart_port *port, u32 ctrl); void (*console_save)(struct uart_port *port); void (*console_restore)(struct uart_port *port); size_t (*suspend_regs_size)(void);}; struct sci_of_data { const struct sci_port_params *params; const struct uart_ops *uart_ops; const struct sci_port_ops *ops; unsigned short regtype; unsigned short type;}; struct sci_port { struct uart_port port; /* Platform configuration */ const struct sci_port_params *params; const struct plat_sci_port *cfg; unsigned int sampling_rate_mask; resource_size_t reg_size; struct mctrl_gpios *gpios; /* Clocks */ struct clk *clks[SCI_NUM_CLKS]; unsigned long clk_rates[SCI_NUM_CLKS]; int irqs[SCIx_NR_IRQS]; char *irqstr[SCIx_NR_IRQS]; struct dma_chan *chan_tx; struct dma_chan *chan_rx; struct reset_control *rstc; struct sci_suspend_regs *suspend_regs; #ifdef CONFIG_SERIAL_SH_SCI_DMA struct dma_chan *chan_tx_saved; struct dma_chan *chan_rx_saved; dma_cookie_t cookie_tx; dma_cookie_t cookie_rx[2]; dma_cookie_t active_rx; dma_addr_t tx_dma_addr; unsigned int tx_dma_len; struct scatterlist sg_rx[2]; void *rx_buf[2]; size_t buf_len_rx; struct work_struct work_tx; struct hrtimer rx_timer; unsigned int rx_timeout; /* microseconds */#endif unsigned int rx_frame; int rx_trigger; struct timer_list rx_fifo_timer; int rx_fifo_timeout; u16 hscif_tot; u8 type; u8 regtype; const struct sci_port_ops *ops; bool has_rtscts; bool autorts; bool tx_occurred;}; #define to_sci_port(uart) container_of((uart), struct sci_port, port) void sci_port_disable(struct sci_port *sci_port);void sci_port_enable(struct sci_port *sci_port); int sci_startup(struct uart_port *port);void sci_shutdown(struct uart_port *port); int sci_scbrr_calc(struct sci_port *s, unsigned int bps, unsigned int *brr, unsigned int *srr, unsigned int *cks); #define min_sr(_port) ffs((_port)->sampling_rate_mask)#define max_sr(_port) fls((_port)->sampling_rate_mask) #ifdef CONFIG_SERIAL_SH_SCI_EARLYCONint __init scix_early_console_setup(struct earlycon_device *device, const struct sci_of_data *data);#endif #endif /* __SH_SCI_COMMON_H__ */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SH_SCI_COMMON_H__
#define __SH_SCI_COMMON_H__
#include <linux/serial_core.h>
/* Private port IDs */
enum SCI_PORT_TYPE {
RSCI_PORT_SCIF16 = BIT(7) | 0,
RSCI_PORT_SCIF32 = BIT(7) | 1,
RSCI_PORT_SCIF32_SINGLE_TCLK = BIT(7) | 2,
};
enum SCI_CLKS {
SCI_FCK, /* Functional Clock */
SCI_SCK, /* Optional External Clock */
SCI_BRG_INT, /* Optional BRG Internal Clock Source */
SCI_SCIF_CLK, /* Optional BRG External Clock Source */
SCI_FCK_DIV4, /* Optional Functional Clock frequency-divided by 4 */
SCI_FCK_DIV16, /* Optional Functional Clock frequency-divided by 16 */
SCI_FCK_DIV64, /* Optional Functional Clock frequency-divided by 64 */
SCI_NUM_CLKS
};
/* Offsets into the sci_port->irqs array */
enum {
SCIx_ERI_IRQ,
SCIx_RXI_IRQ,
SCIx_TXI_IRQ,
SCIx_BRI_IRQ,
SCIx_DRI_IRQ,
SCIx_TEI_IRQ,
SCIx_NR_IRQS,
SCIx_MUX_IRQ = SCIx_NR_IRQS, /* special case */
};
/* Bit x set means sampling rate x + 1 is supported */
#define SCI_SR(x) BIT((x) - 1)
#define SCI_SR_RANGE(x, y) GENMASK((y) - 1, (x) - 1)
void sci_release_port(struct uart_port *port);
int sci_request_port(struct uart_port *port);
void sci_config_port(struct uart_port *port, int flags);
int sci_verify_port(struct uart_port *port, struct serial_struct *ser);
void sci_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate);
struct plat_sci_reg {
u8 offset;
u8 size;
};
struct sci_port_params_bits {
unsigned int rxtx_enable;
unsigned int te_clear;
unsigned int poll_sent_bits;
};
struct sci_common_regs {
unsigned int status;
unsigned int control;
};
/* The actual number of needed registers. This is used by sci only */
#define SCI_NR_REGS 20
struct sci_port_params {
const struct plat_sci_reg regs[SCI_NR_REGS];
const struct sci_common_regs *common_regs;
const struct sci_port_params_bits *param_bits;
unsigned int fifosize;
unsigned int overrun_reg;
unsigned int overrun_mask;
unsigned int sampling_rate_mask;
unsigned int error_mask;
unsigned int error_clear;
};
struct sci_port_ops {
u32 (*read_reg)(struct uart_port *port, int reg);
void (*write_reg)(struct uart_port *port, int reg, int value);
void (*clear_SCxSR)(struct uart_port *port, unsigned int mask);
void (*transmit_chars)(struct uart_port *port);
void (*receive_chars)(struct uart_port *port);
void (*poll_put_char)(struct uart_port *port, unsigned char c);
int (*set_rtrg)(struct uart_port *port, int rx_trig);
int (*rtrg_enabled)(struct uart_port *port);
void (*shutdown_complete)(struct uart_port *port);
void (*prepare_console_write)(struct uart_port *port, u32 ctrl);
void (*finish_console_write)(struct uart_port *port, u32 ctrl);
void (*console_save)(struct uart_port *port);
void (*console_restore)(struct uart_port *port);
size_t (*suspend_regs_size)(void);
};
struct sci_of_data {
const struct sci_port_params *params;
const struct uart_ops *uart_ops;
const struct sci_port_ops *ops;
unsigned short regtype;
unsigned short type;
};
struct sci_port {
struct uart_port port;
/* Platform configuration */
const struct sci_port_params *params;
const struct plat_sci_port *cfg;
unsigned int sampling_rate_mask;
resource_size_t reg_size;
struct mctrl_gpios *gpios;
/* Clocks */
struct clk *clks[SCI_NUM_CLKS];
unsigned long clk_rates[SCI_NUM_CLKS];
int irqs[SCIx_NR_IRQS];
char *irqstr[SCIx_NR_IRQS];
struct dma_chan *chan_tx;
struct dma_chan *chan_rx;
struct reset_control *rstc;
struct sci_suspend_regs *suspend_regs;
#ifdef CONFIG_SERIAL_SH_SCI_DMA
struct dma_chan *chan_tx_saved;
struct dma_chan *chan_rx_saved;
dma_cookie_t cookie_tx;
dma_cookie_t cookie_rx[2];
dma_cookie_t active_rx;
dma_addr_t tx_dma_addr;
unsigned int tx_dma_len;
struct scatterlist sg_rx[2];
void *rx_buf[2];
size_t buf_len_rx;
struct work_struct work_tx;
struct hrtimer rx_timer;
unsigned int rx_timeout; /* microseconds */
#endif
unsigned int rx_frame;
int rx_trigger;
struct timer_list rx_fifo_timer;
int rx_fifo_timeout;
u16 hscif_tot;
u8 type;
u8 regtype;
const struct sci_port_ops *ops;
bool has_rtscts;
bool autorts;
bool tx_occurred;
};
#define to_sci_port(uart) container_of((uart), struct sci_port, port)
void sci_port_disable(struct sci_port *sci_port);
void sci_port_enable(struct sci_port *sci_port);
int sci_startup(struct uart_port *port);
void sci_shutdown(struct uart_port *port);
int sci_scbrr_calc(struct sci_port *s, unsigned int bps, unsigned int *brr,
unsigned int *srr, unsigned int *cks);
#define min_sr(_port) ffs((_port)->sampling_rate_mask)
#define max_sr(_port) fls((_port)->sampling_rate_mask)
#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
int __init scix_early_console_setup(struct earlycon_device *device, const struct sci_of_data *data);
#endif
#endif /* __SH_SCI_COMMON_H__ */