serial: 8250: 8250_omap: Extend driver data to pass FIFO trigger info
Although same 8250 compliant UART IP is reused across different SoC, their integration wrt DMA varies greatly across SoCs. Therefore, different SoC may need to use different FIFO trigger level for DMA event and DMA configuration parameters. Provide a way to pass this information via driver data. This is required to support UART DMA on AM654/J721e SoCs. Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com> Link: https://lore.kernel.org/r/20200319110344.21348-5-vigneshr@ti.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7898984167
commit
7229b84c20
|
@ -105,6 +105,8 @@ struct omap8250_priv {
|
||||||
u8 delayed_restore;
|
u8 delayed_restore;
|
||||||
u16 quot;
|
u16 quot;
|
||||||
|
|
||||||
|
u8 tx_trigger;
|
||||||
|
u8 rx_trigger;
|
||||||
bool is_suspending;
|
bool is_suspending;
|
||||||
int wakeirq;
|
int wakeirq;
|
||||||
int wakeups_enabled;
|
int wakeups_enabled;
|
||||||
|
@ -118,6 +120,17 @@ struct omap8250_priv {
|
||||||
bool throttled;
|
bool throttled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct omap8250_dma_params {
|
||||||
|
u32 rx_size;
|
||||||
|
u8 rx_trigger;
|
||||||
|
u8 tx_trigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct omap8250_platdata {
|
||||||
|
struct omap8250_dma_params *dma_params;
|
||||||
|
u8 habit;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_8250_DMA
|
#ifdef CONFIG_SERIAL_8250_DMA
|
||||||
static void omap_8250_rx_dma_flush(struct uart_8250_port *p);
|
static void omap_8250_rx_dma_flush(struct uart_8250_port *p);
|
||||||
#else
|
#else
|
||||||
|
@ -295,8 +308,8 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
|
||||||
serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_RESTORE(16) |
|
serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_RESTORE(16) |
|
||||||
OMAP_UART_TCR_HALT(52));
|
OMAP_UART_TCR_HALT(52));
|
||||||
serial_out(up, UART_TI752_TLR,
|
serial_out(up, UART_TI752_TLR,
|
||||||
TRIGGER_TLR_MASK(TX_TRIGGER) << UART_TI752_TLR_TX |
|
TRIGGER_TLR_MASK(priv->tx_trigger) << UART_TI752_TLR_TX |
|
||||||
TRIGGER_TLR_MASK(RX_TRIGGER) << UART_TI752_TLR_RX);
|
TRIGGER_TLR_MASK(priv->rx_trigger) << UART_TI752_TLR_RX);
|
||||||
|
|
||||||
serial_out(up, UART_LCR, 0);
|
serial_out(up, UART_LCR, 0);
|
||||||
|
|
||||||
|
@ -435,8 +448,8 @@ static void omap_8250_set_termios(struct uart_port *port,
|
||||||
* This is because threshold and trigger values are the same.
|
* This is because threshold and trigger values are the same.
|
||||||
*/
|
*/
|
||||||
up->fcr = UART_FCR_ENABLE_FIFO;
|
up->fcr = UART_FCR_ENABLE_FIFO;
|
||||||
up->fcr |= TRIGGER_FCR_MASK(TX_TRIGGER) << OMAP_UART_FCR_TX_TRIG;
|
up->fcr |= TRIGGER_FCR_MASK(priv->tx_trigger) << OMAP_UART_FCR_TX_TRIG;
|
||||||
up->fcr |= TRIGGER_FCR_MASK(RX_TRIGGER) << OMAP_UART_FCR_RX_TRIG;
|
up->fcr |= TRIGGER_FCR_MASK(priv->rx_trigger) << OMAP_UART_FCR_RX_TRIG;
|
||||||
|
|
||||||
priv->scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK | OMAP_UART_SCR_TX_EMPTY |
|
priv->scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK | OMAP_UART_SCR_TX_EMPTY |
|
||||||
OMAP_UART_SCR_TX_TRIG_GRANU1_MASK;
|
OMAP_UART_SCR_TX_TRIG_GRANU1_MASK;
|
||||||
|
@ -1092,18 +1105,30 @@ static int omap8250_no_handle_irq(struct uart_port *port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u8 omap4_habit = UART_ERRATA_CLOCK_DISABLE;
|
static struct omap8250_dma_params am33xx_dma = {
|
||||||
static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE;
|
.rx_size = RX_TRIGGER,
|
||||||
static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE;
|
.rx_trigger = RX_TRIGGER,
|
||||||
|
.tx_trigger = TX_TRIGGER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct omap8250_platdata am33xx_platdata = {
|
||||||
|
.dma_params = &am33xx_dma,
|
||||||
|
.habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct omap8250_platdata omap4_platdata = {
|
||||||
|
.dma_params = &am33xx_dma,
|
||||||
|
.habit = UART_ERRATA_CLOCK_DISABLE,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id omap8250_dt_ids[] = {
|
static const struct of_device_id omap8250_dt_ids[] = {
|
||||||
{ .compatible = "ti,am654-uart" },
|
{ .compatible = "ti,am654-uart" },
|
||||||
{ .compatible = "ti,omap2-uart" },
|
{ .compatible = "ti,omap2-uart" },
|
||||||
{ .compatible = "ti,omap3-uart" },
|
{ .compatible = "ti,omap3-uart" },
|
||||||
{ .compatible = "ti,omap4-uart", .data = &omap4_habit, },
|
{ .compatible = "ti,omap4-uart", .data = &omap4_platdata, },
|
||||||
{ .compatible = "ti,am3352-uart", .data = &am3352_habit, },
|
{ .compatible = "ti,am3352-uart", .data = &am33xx_platdata, },
|
||||||
{ .compatible = "ti,am4372-uart", .data = &am3352_habit, },
|
{ .compatible = "ti,am4372-uart", .data = &am33xx_platdata, },
|
||||||
{ .compatible = "ti,dra742-uart", .data = &dra742_habit, },
|
{ .compatible = "ti,dra742-uart", .data = &omap4_platdata, },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, omap8250_dt_ids);
|
MODULE_DEVICE_TABLE(of, omap8250_dt_ids);
|
||||||
|
@ -1114,10 +1139,10 @@ static int omap8250_probe(struct platform_device *pdev)
|
||||||
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
struct omap8250_priv *priv;
|
struct omap8250_priv *priv;
|
||||||
|
const struct omap8250_platdata *pdata;
|
||||||
struct uart_8250_port up;
|
struct uart_8250_port up;
|
||||||
int ret;
|
int ret;
|
||||||
void __iomem *membase;
|
void __iomem *membase;
|
||||||
const struct of_device_id *id;
|
|
||||||
|
|
||||||
if (!regs || !irq) {
|
if (!regs || !irq) {
|
||||||
dev_err(&pdev->dev, "missing registers or irq\n");
|
dev_err(&pdev->dev, "missing registers or irq\n");
|
||||||
|
@ -1198,9 +1223,9 @@ static int omap8250_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
priv->wakeirq = irq_of_parse_and_map(np, 1);
|
priv->wakeirq = irq_of_parse_and_map(np, 1);
|
||||||
|
|
||||||
id = of_match_device(of_match_ptr(omap8250_dt_ids), &pdev->dev);
|
pdata = of_device_get_match_data(&pdev->dev);
|
||||||
if (id && id->data)
|
if (pdata)
|
||||||
priv->habit |= *(u8 *)id->data;
|
priv->habit |= pdata->habit;
|
||||||
|
|
||||||
if (!up.port.uartclk) {
|
if (!up.port.uartclk) {
|
||||||
up.port.uartclk = DEFAULT_CLK_SPEED;
|
up.port.uartclk = DEFAULT_CLK_SPEED;
|
||||||
|
@ -1237,6 +1262,8 @@ static int omap8250_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
omap_serial_fill_features_erratas(&up, priv);
|
omap_serial_fill_features_erratas(&up, priv);
|
||||||
up.port.handle_irq = omap8250_no_handle_irq;
|
up.port.handle_irq = omap8250_no_handle_irq;
|
||||||
|
priv->rx_trigger = RX_TRIGGER;
|
||||||
|
priv->tx_trigger = TX_TRIGGER;
|
||||||
#ifdef CONFIG_SERIAL_8250_DMA
|
#ifdef CONFIG_SERIAL_8250_DMA
|
||||||
/*
|
/*
|
||||||
* Oh DMA support. If there are no DMA properties in the DT then
|
* Oh DMA support. If there are no DMA properties in the DT then
|
||||||
|
@ -1248,13 +1275,26 @@ static int omap8250_probe(struct platform_device *pdev)
|
||||||
*/
|
*/
|
||||||
ret = of_property_count_strings(np, "dma-names");
|
ret = of_property_count_strings(np, "dma-names");
|
||||||
if (ret == 2) {
|
if (ret == 2) {
|
||||||
|
struct omap8250_dma_params *dma_params = NULL;
|
||||||
|
|
||||||
up.dma = &priv->omap8250_dma;
|
up.dma = &priv->omap8250_dma;
|
||||||
priv->omap8250_dma.fn = the_no_dma_filter_fn;
|
up.dma->fn = the_no_dma_filter_fn;
|
||||||
priv->omap8250_dma.tx_dma = omap_8250_tx_dma;
|
up.dma->tx_dma = omap_8250_tx_dma;
|
||||||
priv->omap8250_dma.rx_dma = omap_8250_rx_dma;
|
up.dma->rx_dma = omap_8250_rx_dma;
|
||||||
priv->omap8250_dma.rx_size = RX_TRIGGER;
|
if (pdata)
|
||||||
priv->omap8250_dma.rxconf.src_maxburst = RX_TRIGGER;
|
dma_params = pdata->dma_params;
|
||||||
priv->omap8250_dma.txconf.dst_maxburst = TX_TRIGGER;
|
|
||||||
|
if (dma_params) {
|
||||||
|
up.dma->rx_size = dma_params->rx_size;
|
||||||
|
up.dma->rxconf.src_maxburst = dma_params->rx_trigger;
|
||||||
|
up.dma->txconf.dst_maxburst = dma_params->tx_trigger;
|
||||||
|
priv->rx_trigger = dma_params->rx_trigger;
|
||||||
|
priv->tx_trigger = dma_params->tx_trigger;
|
||||||
|
} else {
|
||||||
|
up.dma->rx_size = RX_TRIGGER;
|
||||||
|
up.dma->rxconf.src_maxburst = RX_TRIGGER;
|
||||||
|
up.dma->txconf.dst_maxburst = TX_TRIGGER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ret = serial8250_register_8250_port(&up);
|
ret = serial8250_register_8250_port(&up);
|
||||||
|
|
Loading…
Reference in New Issue