Add support for the uart classes to set their default register shift value.
This is needed with the pl011 driver. Before this change it would default to a shift of 0, however the hardware places the registers at 4-byte addresses meaning the value should be 2. This patch fixes this for the pl011 when configured using the fdt. The other drivers have a default value of 0 to keep this a no-op. MFC after: 1 week
This commit is contained in:
parent
2574218578
commit
405ada37fb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=281438
@ -724,7 +724,8 @@ struct uart_class uart_aml8726_class = {
|
|||||||
sizeof(struct uart_softc),
|
sizeof(struct uart_softc),
|
||||||
.uc_ops = &aml8726_uart_ops,
|
.uc_ops = &aml8726_uart_ops,
|
||||||
.uc_range = 24,
|
.uc_range = 24,
|
||||||
.uc_rclk = 0
|
.uc_rclk = 0,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ofw_compat_data compat_data[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
|
@ -276,7 +276,8 @@ static struct uart_class uart_vybrid_class = {
|
|||||||
sizeof(struct vf_uart_softc),
|
sizeof(struct vf_uart_softc),
|
||||||
.uc_ops = &uart_vybrid_ops,
|
.uc_ops = &uart_vybrid_ops,
|
||||||
.uc_range = 0x100,
|
.uc_range = 0x100,
|
||||||
.uc_rclk = 24000000 /* TODO: get value from CCM */
|
.uc_rclk = 24000000, /* TODO: get value from CCM */
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ofw_compat_data compat_data[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
|
@ -380,6 +380,7 @@ static struct uart_class uart_exynos4210_class = {
|
|||||||
.uc_ops = &uart_exynos4210_ops,
|
.uc_ops = &uart_exynos4210_ops,
|
||||||
.uc_range = 8,
|
.uc_range = 8,
|
||||||
.uc_rclk = 0,
|
.uc_rclk = 0,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ofw_compat_data compat_data[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
|
@ -402,4 +402,5 @@ struct uart_class uart_s3c2410_class = {
|
|||||||
.uc_ops = &uart_s3c2410_ops,
|
.uc_ops = &uart_s3c2410_ops,
|
||||||
.uc_range = 8,
|
.uc_range = 8,
|
||||||
.uc_rclk = 0,
|
.uc_rclk = 0,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
@ -70,6 +70,7 @@ struct uart_class {
|
|||||||
struct uart_ops *uc_ops; /* Low-level console operations. */
|
struct uart_ops *uc_ops; /* Low-level console operations. */
|
||||||
u_int uc_range; /* Bus space address range. */
|
u_int uc_range; /* Bus space address range. */
|
||||||
u_int uc_rclk; /* Default rclk for this device. */
|
u_int uc_rclk; /* Default rclk for this device. */
|
||||||
|
u_int uc_rshift; /* Default regshift for this device. */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uart_softc {
|
struct uart_softc {
|
||||||
|
@ -83,16 +83,10 @@ uart_fdt_get_clock(phandle_t node, pcell_t *cell)
|
|||||||
int
|
int
|
||||||
uart_fdt_get_shift(phandle_t node, pcell_t *cell)
|
uart_fdt_get_shift(phandle_t node, pcell_t *cell)
|
||||||
{
|
{
|
||||||
#ifdef __aarch64__
|
|
||||||
#define DEFAULT_SHIFT 2
|
|
||||||
#else
|
|
||||||
#define DEFAULT_SHIFT 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((OF_getencprop(node, "reg-shift", cell, sizeof(*cell))) <= 0)
|
if ((OF_getencprop(node, "reg-shift", cell, sizeof(*cell))) <= 0)
|
||||||
*cell = DEFAULT_SHIFT;
|
return (-1);
|
||||||
return (0);
|
return (0);
|
||||||
#undef DEFAULT_SHIFT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t
|
static uintptr_t
|
||||||
@ -130,7 +124,8 @@ uart_fdt_probe(device_t dev)
|
|||||||
|
|
||||||
if ((err = uart_fdt_get_clock(node, &clock)) != 0)
|
if ((err = uart_fdt_get_clock(node, &clock)) != 0)
|
||||||
return (err);
|
return (err);
|
||||||
uart_fdt_get_shift(node, &shift);
|
if (uart_fdt_get_shift(node, &shift) != 0)
|
||||||
|
shift = uart_getregshift(sc->sc_class);
|
||||||
|
|
||||||
return (uart_bus_probe(dev, (int)shift, (int)clock, 0, 0));
|
return (uart_bus_probe(dev, (int)shift, (int)clock, 0, 0));
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,12 @@ uart_getrange(struct uart_class *uc)
|
|||||||
return ((uc != NULL) ? uc->uc_range : 0);
|
return ((uc != NULL) ? uc->uc_range : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u_int
|
||||||
|
uart_getregshift(struct uart_class *uc)
|
||||||
|
{
|
||||||
|
return ((uc != NULL) ? uc->uc_rshift : 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Schedule a soft interrupt. We do this on the 0 to !0 transition
|
* Schedule a soft interrupt. We do this on the 0 to !0 transition
|
||||||
* of the TTY pending interrupt status.
|
* of the TTY pending interrupt status.
|
||||||
|
@ -79,6 +79,7 @@ int uart_getenv(int, struct uart_devinfo *, struct uart_class *);
|
|||||||
const char *uart_getname(struct uart_class *);
|
const char *uart_getname(struct uart_class *);
|
||||||
struct uart_ops *uart_getops(struct uart_class *);
|
struct uart_ops *uart_getops(struct uart_class *);
|
||||||
int uart_getrange(struct uart_class *);
|
int uart_getrange(struct uart_class *);
|
||||||
|
u_int uart_getregshift(struct uart_class *);
|
||||||
|
|
||||||
void uart_add_sysdev(struct uart_devinfo *);
|
void uart_add_sysdev(struct uart_devinfo *);
|
||||||
|
|
||||||
|
@ -164,15 +164,6 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
|
|||||||
if (node == -1) /* Can't find anything */
|
if (node == -1) /* Can't find anything */
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve serial attributes.
|
|
||||||
*/
|
|
||||||
uart_fdt_get_shift(node, &shift);
|
|
||||||
if (OF_getprop(node, "current-speed", &br, sizeof(br)) <= 0)
|
|
||||||
br = 0;
|
|
||||||
else
|
|
||||||
br = fdt32_to_cpu(br);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check old style of UART definition first. Unfortunately, the common
|
* Check old style of UART definition first. Unfortunately, the common
|
||||||
* FDT processing is not possible if we have clock, power domains and
|
* FDT processing is not possible if we have clock, power domains and
|
||||||
@ -191,6 +182,17 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
|
|||||||
rclk = 0;
|
rclk = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve serial attributes.
|
||||||
|
*/
|
||||||
|
if (uart_fdt_get_shift(node, &shift) != 0)
|
||||||
|
shift = uart_getregshift(class);
|
||||||
|
|
||||||
|
if (OF_getprop(node, "current-speed", &br, sizeof(br)) <= 0)
|
||||||
|
br = 0;
|
||||||
|
else
|
||||||
|
br = fdt32_to_cpu(br);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finalize configuration.
|
* Finalize configuration.
|
||||||
*/
|
*/
|
||||||
|
@ -298,7 +298,8 @@ static struct uart_class uart_imx_class = {
|
|||||||
sizeof(struct imx_uart_softc),
|
sizeof(struct imx_uart_softc),
|
||||||
.uc_ops = &uart_imx_uart_ops,
|
.uc_ops = &uart_imx_uart_ops,
|
||||||
.uc_range = 0x100,
|
.uc_range = 0x100,
|
||||||
.uc_rclk = 24000000 /* TODO: get value from CCM */
|
.uc_rclk = 24000000, /* TODO: get value from CCM */
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ofw_compat_data compat_data[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
|
@ -428,7 +428,8 @@ static struct uart_class uart_lpc_class = {
|
|||||||
sizeof(struct lpc_ns8250_softc),
|
sizeof(struct lpc_ns8250_softc),
|
||||||
.uc_ops = &uart_lpc_ns8250_ops,
|
.uc_ops = &uart_lpc_ns8250_ops,
|
||||||
.uc_range = 8,
|
.uc_range = 8,
|
||||||
.uc_rclk = DEFAULT_RCLK
|
.uc_rclk = DEFAULT_RCLK,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ofw_compat_data compat_data[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
|
@ -566,6 +566,7 @@ static struct uart_class uart_msm_class = {
|
|||||||
.uc_ops = &uart_msm_ops,
|
.uc_ops = &uart_msm_ops,
|
||||||
.uc_range = 8,
|
.uc_range = 8,
|
||||||
.uc_rclk = DEF_CLK,
|
.uc_rclk = DEF_CLK,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ofw_compat_data compat_data[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
|
@ -378,7 +378,8 @@ struct uart_class uart_ns8250_class = {
|
|||||||
sizeof(struct ns8250_softc),
|
sizeof(struct ns8250_softc),
|
||||||
.uc_ops = &uart_ns8250_ops,
|
.uc_ops = &uart_ns8250_ops,
|
||||||
.uc_range = 8,
|
.uc_range = 8,
|
||||||
.uc_rclk = DEFAULT_RCLK
|
.uc_rclk = DEFAULT_RCLK,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef FDT
|
#ifdef FDT
|
||||||
|
@ -273,7 +273,8 @@ static struct uart_class uart_pl011_class = {
|
|||||||
sizeof(struct uart_pl011_softc),
|
sizeof(struct uart_pl011_softc),
|
||||||
.uc_ops = &uart_pl011_ops,
|
.uc_ops = &uart_pl011_ops,
|
||||||
.uc_range = 0x48,
|
.uc_range = 0x48,
|
||||||
.uc_rclk = 0
|
.uc_rclk = 0,
|
||||||
|
.uc_rshift = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ofw_compat_data compat_data[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
|
@ -271,7 +271,8 @@ struct uart_class uart_quicc_class = {
|
|||||||
sizeof(struct quicc_softc),
|
sizeof(struct quicc_softc),
|
||||||
.uc_ops = &uart_quicc_ops,
|
.uc_ops = &uart_quicc_ops,
|
||||||
.uc_range = 2,
|
.uc_range = 2,
|
||||||
.uc_rclk = DEFAULT_RCLK
|
.uc_rclk = DEFAULT_RCLK,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIGCHG(c, i, s, d) \
|
#define SIGCHG(c, i, s, d) \
|
||||||
|
@ -391,7 +391,8 @@ struct uart_class uart_sab82532_class = {
|
|||||||
sizeof(struct sab82532_softc),
|
sizeof(struct sab82532_softc),
|
||||||
.uc_ops = &uart_sab82532_ops,
|
.uc_ops = &uart_sab82532_ops,
|
||||||
.uc_range = 64,
|
.uc_range = 64,
|
||||||
.uc_rclk = DEFAULT_RCLK
|
.uc_rclk = DEFAULT_RCLK,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIGCHG(c, i, s, d) \
|
#define SIGCHG(c, i, s, d) \
|
||||||
|
@ -137,7 +137,8 @@ static struct uart_class uart_ti8250_class = {
|
|||||||
sizeof(struct ti8250_softc),
|
sizeof(struct ti8250_softc),
|
||||||
.uc_ops = &uart_ns8250_ops,
|
.uc_ops = &uart_ns8250_ops,
|
||||||
.uc_range = 0x88,
|
.uc_range = 0x88,
|
||||||
.uc_rclk = 48000000
|
.uc_rclk = 48000000,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
static struct ofw_compat_data compat_data[] = {
|
static struct ofw_compat_data compat_data[] = {
|
||||||
{"ti,ns16550", (uintptr_t)&uart_ti8250_class},
|
{"ti,ns16550", (uintptr_t)&uart_ti8250_class},
|
||||||
|
@ -307,7 +307,8 @@ struct uart_class uart_z8530_class = {
|
|||||||
sizeof(struct z8530_softc),
|
sizeof(struct z8530_softc),
|
||||||
.uc_ops = &uart_z8530_ops,
|
.uc_ops = &uart_z8530_ops,
|
||||||
.uc_range = 2,
|
.uc_range = 2,
|
||||||
.uc_rclk = DEFAULT_RCLK
|
.uc_rclk = DEFAULT_RCLK,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIGCHG(c, i, s, d) \
|
#define SIGCHG(c, i, s, d) \
|
||||||
|
@ -175,7 +175,8 @@ struct uart_class uart_adm5120_uart_class = {
|
|||||||
sizeof(struct adm5120_uart_softc),
|
sizeof(struct adm5120_uart_softc),
|
||||||
.uc_ops = &uart_adm5120_uart_ops,
|
.uc_ops = &uart_adm5120_uart_ops,
|
||||||
.uc_range = 1, /* use hinted range */
|
.uc_range = 1, /* use hinted range */
|
||||||
.uc_rclk = 62500000
|
.uc_rclk = 62500000,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIGCHG(c, i, s, d) \
|
#define SIGCHG(c, i, s, d) \
|
||||||
|
@ -351,7 +351,8 @@ struct uart_class uart_ar933x_class = {
|
|||||||
sizeof(struct ar933x_softc),
|
sizeof(struct ar933x_softc),
|
||||||
.uc_ops = &uart_ar933x_ops,
|
.uc_ops = &uart_ar933x_ops,
|
||||||
.uc_range = 8,
|
.uc_range = 8,
|
||||||
.uc_rclk = DEFAULT_RCLK
|
.uc_rclk = DEFAULT_RCLK,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIGCHG(c, i, s, d) \
|
#define SIGCHG(c, i, s, d) \
|
||||||
|
@ -424,7 +424,8 @@ struct uart_class uart_oct16550_class = {
|
|||||||
sizeof(struct oct16550_softc),
|
sizeof(struct oct16550_softc),
|
||||||
.uc_ops = &uart_oct16550_ops,
|
.uc_ops = &uart_oct16550_ops,
|
||||||
.uc_range = 8 << 3,
|
.uc_range = 8 << 3,
|
||||||
.uc_rclk = 0
|
.uc_rclk = 0,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIGCHG(c, i, s, d) \
|
#define SIGCHG(c, i, s, d) \
|
||||||
|
@ -217,7 +217,8 @@ struct uart_class uart_rt305x_uart_class = {
|
|||||||
sizeof(struct rt305x_uart_softc),
|
sizeof(struct rt305x_uart_softc),
|
||||||
.uc_ops = &uart_rt305x_uart_ops,
|
.uc_ops = &uart_rt305x_uart_ops,
|
||||||
.uc_range = 1, /* use hinted range */
|
.uc_range = 1, /* use hinted range */
|
||||||
.uc_rclk = SYSTEM_CLOCK
|
.uc_rclk = SYSTEM_CLOCK,
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIGCHG(c, i, s, d) \
|
#define SIGCHG(c, i, s, d) \
|
||||||
|
@ -813,7 +813,8 @@ struct uart_class uart_sbbc_class = {
|
|||||||
sizeof(struct uart_softc),
|
sizeof(struct uart_softc),
|
||||||
.uc_ops = &sbbc_uart_ops,
|
.uc_ops = &sbbc_uart_ops,
|
||||||
.uc_range = 1,
|
.uc_range = 1,
|
||||||
.uc_rclk = 0x5bbc /* arbitrary */
|
.uc_rclk = 0x5bbc, /* arbitrary */
|
||||||
|
.uc_rshift = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SIGCHG(c, i, s, d) \
|
#define SIGCHG(c, i, s, d) \
|
||||||
|
Loading…
Reference in New Issue
Block a user