Commit 7229b84c authored by Vignesh Raghavendra's avatar Vignesh Raghavendra Committed by Greg Kroah-Hartman

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: default avatarVignesh Raghavendra <vigneshr@ti.com>
Link: https://lore.kernel.org/r/20200319110344.21348-5-vigneshr@ti.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 78989841
...@@ -105,6 +105,8 @@ struct omap8250_priv { ...@@ -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 { ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment