|
@@ -44,6 +44,13 @@
|
|
|
#include <plat/dmtimer.h>
|
|
|
#include <plat/omap-serial.h>
|
|
|
|
|
|
+#define UART_BUILD_REVISION(x, y) (((x) << 8) | (y))
|
|
|
+
|
|
|
+#define OMAP_UART_REV_42 0x0402
|
|
|
+#define OMAP_UART_REV_46 0x0406
|
|
|
+#define OMAP_UART_REV_52 0x0502
|
|
|
+#define OMAP_UART_REV_63 0x0603
|
|
|
+
|
|
|
#define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/
|
|
|
|
|
|
/* SCR register bitmasks */
|
|
@@ -53,6 +60,17 @@
|
|
|
#define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT 6
|
|
|
#define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6)
|
|
|
|
|
|
+/* MVR register bitmasks */
|
|
|
+#define OMAP_UART_MVR_SCHEME_SHIFT 30
|
|
|
+
|
|
|
+#define OMAP_UART_LEGACY_MVR_MAJ_MASK 0xf0
|
|
|
+#define OMAP_UART_LEGACY_MVR_MAJ_SHIFT 4
|
|
|
+#define OMAP_UART_LEGACY_MVR_MIN_MASK 0x0f
|
|
|
+
|
|
|
+#define OMAP_UART_MVR_MAJ_MASK 0x700
|
|
|
+#define OMAP_UART_MVR_MAJ_SHIFT 8
|
|
|
+#define OMAP_UART_MVR_MIN_MASK 0x3f
|
|
|
+
|
|
|
static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
|
|
|
|
|
|
/* Forward declaration of functions */
|
|
@@ -1346,6 +1364,59 @@ static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+static void omap_serial_fill_features_erratas(struct uart_omap_port *up)
|
|
|
+{
|
|
|
+ u32 mvr, scheme;
|
|
|
+ u16 revision, major, minor;
|
|
|
+
|
|
|
+ mvr = serial_in(up, UART_OMAP_MVER);
|
|
|
+
|
|
|
+ /* Check revision register scheme */
|
|
|
+ scheme = mvr >> OMAP_UART_MVR_SCHEME_SHIFT;
|
|
|
+
|
|
|
+ switch (scheme) {
|
|
|
+ case 0: /* Legacy Scheme: OMAP2/3 */
|
|
|
+ /* MINOR_REV[0:4], MAJOR_REV[4:7] */
|
|
|
+ major = (mvr & OMAP_UART_LEGACY_MVR_MAJ_MASK) >>
|
|
|
+ OMAP_UART_LEGACY_MVR_MAJ_SHIFT;
|
|
|
+ minor = (mvr & OMAP_UART_LEGACY_MVR_MIN_MASK);
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ /* New Scheme: OMAP4+ */
|
|
|
+ /* MINOR_REV[0:5], MAJOR_REV[8:10] */
|
|
|
+ major = (mvr & OMAP_UART_MVR_MAJ_MASK) >>
|
|
|
+ OMAP_UART_MVR_MAJ_SHIFT;
|
|
|
+ minor = (mvr & OMAP_UART_MVR_MIN_MASK);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ dev_warn(&up->pdev->dev,
|
|
|
+ "Unknown %s revision, defaulting to highest\n",
|
|
|
+ up->name);
|
|
|
+ /* highest possible revision */
|
|
|
+ major = 0xff;
|
|
|
+ minor = 0xff;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* normalize revision for the driver */
|
|
|
+ revision = UART_BUILD_REVISION(major, minor);
|
|
|
+
|
|
|
+ switch (revision) {
|
|
|
+ case OMAP_UART_REV_46:
|
|
|
+ up->errata |= (UART_ERRATA_i202_MDR1_ACCESS |
|
|
|
+ UART_ERRATA_i291_DMA_FORCEIDLE);
|
|
|
+ break;
|
|
|
+ case OMAP_UART_REV_52:
|
|
|
+ up->errata |= (UART_ERRATA_i202_MDR1_ACCESS |
|
|
|
+ UART_ERRATA_i291_DMA_FORCEIDLE);
|
|
|
+ break;
|
|
|
+ case OMAP_UART_REV_63:
|
|
|
+ up->errata |= UART_ERRATA_i202_MDR1_ACCESS;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev)
|
|
|
{
|
|
|
struct omap_uart_port_info *omap_up_info;
|
|
@@ -1443,7 +1514,6 @@ static int serial_omap_probe(struct platform_device *pdev)
|
|
|
"%d\n", DEFAULT_CLK_SPEED);
|
|
|
}
|
|
|
up->uart_dma.uart_base = mem->start;
|
|
|
- up->errata = omap_up_info->errata;
|
|
|
|
|
|
if (omap_up_info->dma_enabled) {
|
|
|
up->uart_dma.uart_dma_tx = dma_tx->start;
|
|
@@ -1473,6 +1543,8 @@ static int serial_omap_probe(struct platform_device *pdev)
|
|
|
pm_runtime_enable(&pdev->dev);
|
|
|
pm_runtime_get_sync(&pdev->dev);
|
|
|
|
|
|
+ omap_serial_fill_features_erratas(up);
|
|
|
+
|
|
|
ui[up->port.line] = up;
|
|
|
serial_omap_add_console_port(up);
|
|
|
|