NVIDIA: SAUCE: serial: pl011: add nvidia pl011 controller support
BugLink: https://bugs.launchpad.net/bugs/2080908 Add support for Nvidia's UART controller based on pl011. http://nvbugs/3414248 http://nvbugs/4754882 Signed-off-by: kartik <kkartik@nvidia.com> Tested-by: Petlozu Pravareshwar <petlozup@nvidia.com> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Acked-by: Noah Wager <noah.wager@canonical.com> Acked-by: Jacob Martin <jacob.martin@canonical.com> Signed-off-by: Noah Wager <noah.wager@canonical.com>
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
#include <linux/amba/bus.h>
|
||||
#include <linux/amba/serial.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
@@ -114,6 +115,8 @@ struct vendor_data {
|
||||
bool cts_event_workaround;
|
||||
bool always_enabled;
|
||||
bool fixed_options;
|
||||
bool enable_car;
|
||||
bool dma_workaround;
|
||||
|
||||
unsigned int (*get_fifosize)(struct amba_device *dev);
|
||||
};
|
||||
@@ -123,6 +126,23 @@ static unsigned int get_fifosize_arm(struct amba_device *dev)
|
||||
return amba_rev(dev) < 3 ? 16 : 32;
|
||||
}
|
||||
|
||||
static struct vendor_data vendor_nvidia = {
|
||||
.reg_offset = pl011_std_offsets,
|
||||
.ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
|
||||
.fr_busy = UART01x_FR_BUSY,
|
||||
.fr_dsr = UART01x_FR_DSR,
|
||||
.fr_cts = UART01x_FR_CTS,
|
||||
.fr_ri = UART011_FR_RI,
|
||||
.oversampling = false,
|
||||
.dma_threshold = false,
|
||||
.cts_event_workaround = false,
|
||||
.always_enabled = false,
|
||||
.fixed_options = false,
|
||||
.enable_car = true,
|
||||
.dma_workaround = true,
|
||||
.get_fifosize = get_fifosize_arm,
|
||||
};
|
||||
|
||||
static struct vendor_data vendor_arm = {
|
||||
.reg_offset = pl011_std_offsets,
|
||||
.ifls = UART011_IFLS_RX4_8 | UART011_IFLS_TX4_8,
|
||||
@@ -255,6 +275,7 @@ struct uart_amba_port {
|
||||
struct uart_port port;
|
||||
const u16 *reg_offset;
|
||||
struct clk *clk;
|
||||
struct reset_control *rst;
|
||||
const struct vendor_data *vendor;
|
||||
unsigned int dmacr; /* dma control reg */
|
||||
unsigned int im; /* interrupt mask */
|
||||
@@ -609,6 +630,19 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap)
|
||||
*/
|
||||
count -= 1;
|
||||
|
||||
/*
|
||||
* Tegra GPC DMA driver requires the data to be multiple of burst size.
|
||||
* Make count a multiple of burst size.
|
||||
*/
|
||||
if (uap->vendor->dma_workaround) {
|
||||
count -= (count % (uap->fifosize >> 1));
|
||||
|
||||
if (count < (uap->fifosize >> 1)) {
|
||||
uap->dmatx.queued = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Else proceed to copy the TX chars to the DMA buffer and fire DMA */
|
||||
if (count > PL011_DMA_BUFFER_SIZE)
|
||||
count = PL011_DMA_BUFFER_SIZE;
|
||||
@@ -2752,6 +2786,16 @@ static int pl011_register_port(struct uart_amba_port *uap)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
/* Reset the controller and enable clock for initial reg_write.
|
||||
* This is required for Tegra Pl011 controller.
|
||||
*/
|
||||
if (uap->vendor->enable_car) {
|
||||
reset_control_assert(uap->rst);
|
||||
udelay(10);
|
||||
reset_control_deassert(uap->rst);
|
||||
clk_prepare_enable(uap->clk);
|
||||
}
|
||||
|
||||
/* Ensure interrupts from this UART are masked and cleared */
|
||||
pl011_write(0, uap, REG_IMSC);
|
||||
pl011_write(0xffff, uap, REG_ICR);
|
||||
@@ -2802,6 +2846,13 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
if (IS_ERR(uap->clk))
|
||||
return PTR_ERR(uap->clk);
|
||||
|
||||
if (vendor->enable_car) {
|
||||
uap->rst = devm_reset_control_get_exclusive(&dev->dev,
|
||||
"serial");
|
||||
if (IS_ERR(uap->rst))
|
||||
return PTR_ERR(uap->rst);
|
||||
}
|
||||
|
||||
uap->reg_offset = vendor->reg_offset;
|
||||
uap->vendor = vendor;
|
||||
uap->fifosize = vendor->get_fifosize(dev);
|
||||
@@ -2985,6 +3036,11 @@ static const struct amba_id pl011_ids[] = {
|
||||
.mask = 0x00ffffff,
|
||||
.data = &vendor_st,
|
||||
},
|
||||
{
|
||||
.id = 0x00051011,
|
||||
.mask = 0x00ffffff,
|
||||
.data = &vendor_nvidia,
|
||||
},
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user