linux/drivers/tty/serial
Stephen Boyd 98952bf510 tty: serial: msm: Support more bauds
The msm_find_best_baud() function is written with the assumption
that the port->uartclk rate is fixed to a particular rate at boot
time, but now this driver changes that clk rate at runtime when
the baud is changed.

The way the hardware works is that an input clk rate comes from
the clk controller into the uart hw block. That rate is typically
1843200 or 3686400 Hz. That rate can then be divided by an
internal divider in the hw block to achieve a particular baud on
the serial wire. msm_find_best_baud() is looking for that divider
value.

A few things are wrong with the way the code is written. First,
it assumes that the maximum baud that the uart can support if the
clk rate is fixed at boot is 460800, which would correspond to an
input clk rate of 230400 * 16 == 3686400 Hz.  Except some devices
have a boot rate of 1843200 Hz or max baud of 115200, so
achieving 230400 on those devices doesn't work at all because we
don't increase the clk rate unless max baud is 460800.

Second, we can't achieve bauds higher than 460800 that require
anything besides a divisor of 1, because we always call
msm_find_best_baud() with a fixed port->uartclk rate that will
eventually be changed after we calculate the divisor. So if we
need to get a baud of 500000, we'll just multiply that by 16 and
hope that the clk can give us 500000 * 16 == 8000000 Hz, which it
typically can't do. To really achieve 500000 baud, we need to get
an input clk rate of 24000000 Hz and then divide that by 3 inside
the uart hardware.

Finally, we return success for bauds even when we can't actually
achieve them. This means that when the user asks for 500000 baud,
we actually get 921600 right now, but the user doesn't know that.

Fix all of this by searching through the divisor and clk rate
space with a combination of clk_round_rate() and baud
calculations, keeping track of the best clk rate and divisor we
find if we can't get an exact match. Typically we can get an
exact match with a divisor of 1, but sometimes we need to keep
track and try more frequencies. On my msm8916 device, this
results in all standard bauds in baud_table being supported
except for 1800, 576000, 1152000, and 4000000.

Fixes: 850b37a71b ("tty: serial: msm: Remove 115.2 Kbps maximum baud rate limitation")
Cc: "Ivan T. Ivanov" <iivanov.xz@gmail.com>
Cc: Matthew McClintock <mmcclint@codeaurora.org>
Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
Tested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Acked-by: Andy Gross <andy.gross@linaro.org>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Tested-by: Cristian Prundeanu <cprundea@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-04-30 09:26:55 -07:00
..
8250 serial: 8250_pci: fix divide error bug if baud rate is 0 2016-04-28 20:07:10 -07:00
cpm_uart tty: serial: cpm_uart: Fix module autoload for OF platform driver 2015-10-04 19:09:21 +01:00
jsm tty: serial: jsm_tty: fixed redundant variable issue. 2016-02-07 13:36:09 -08:00
21285.c
altera_jtaguart.c drivers/tty/serial: altera: fix typos in #endif comments 2015-05-06 22:26:58 +02:00
altera_uart.c serial: altera_uart: Use of_property_read_u32 instead of open-coding it 2015-10-04 17:47:49 +01:00
amba-pl010.c
amba-pl011.c tty: amba-pl011: Use 32-bit accesses for SBSA UART 2016-04-30 09:26:55 -07:00
amba-pl011.h tty: amba-pl011: clean up LCR register offsets 2015-12-13 19:59:48 -08:00
apbuart.c tty: serial: apbuart: Fix module autoload for OF platform driver 2015-10-04 19:09:21 +01:00
apbuart.h
ar933x_uart.c serial: ar933x_uart: Fix off-by-one for checking valid alias id 2015-03-07 03:20:25 +01:00
arc_uart.c earlycon: Use common framework for earlycon declarations 2016-02-06 22:07:37 -08:00
atmel_serial.c tty/serial: atmel: fix hardware handshake selection 2016-04-28 20:07:10 -07:00
bcm63xx_uart.c serial/bcm63xx_uart: Deinline wait_for_xmitr, save 374 bytes 2015-12-13 19:59:48 -08:00
bfin_sport_uart.c
bfin_sport_uart.h
bfin_uart.c serial:bfin-uart:Remove 'struct timeval' 2015-12-13 19:59:48 -08:00
clps711x.c serial: clps711x: Fix bad usage of IS_ERR_VALUE 2016-02-14 17:39:36 -08:00
crisv10.c tty: Replace ASYNC_INITIALIZED bit and update atomically 2016-04-30 09:26:55 -07:00
crisv10.h
digicolor-usart.c tty/serial: digicolor: Fix bad usage of IS_ERR_VALUE 2016-02-14 17:39:36 -08:00
dz.c
dz.h
earlycon-arm-semihost.c
earlycon.c serial: earlycon: Show the earlycon "driver" in banner 2016-02-06 22:07:37 -08:00
efm32-uart.c
etraxfs-uart.c serial: etraxfs-uart: Fix crash 2015-11-20 16:19:54 -08:00
fsl_lpuart.c serial: fsl_lpuart: add earlycon support 2015-10-17 21:18:30 -07:00
icom.c tty: Remove unused SERIAL_DO_RESTART define 2015-12-13 19:59:48 -08:00
icom.h
ifx6x60.c serial: ifx6x60: avoid uninitialized variable use 2016-03-07 16:11:14 -08:00
ifx6x60.h
imx.c serial: imx: implement DSR irq handling for DTE mode 2016-04-30 09:26:55 -07:00
ioc3_serial.c tty: ioc3_serial.c: move assignment out of if () block 2015-05-10 19:04:17 +02:00
ioc4_serial.c tty: ioc4_serial.c: move assignment out of if () block 2015-05-10 19:04:17 +02:00
ip22zilog.c
ip22zilog.h
Kconfig serial: mxs-auart: add Alphascale ASM9260 support 2016-04-30 09:26:55 -07:00
kgdb_nmi.c serial: kgdb_nmi: Use bool function return values of true/false not 1/0 2015-05-06 22:26:57 +02:00
kgdboc.c
lantiq.c drivers/tty: make serial/lantic.c driver explicitly non-modular 2015-07-23 18:27:41 -07:00
lpc32xx_hs.c tty: serial: lpc32xx_hs: fix handling platform_get_irq result 2015-10-04 19:09:21 +01:00
m32r_sio.c TTY: serial/m32r_sio, remove unused members 2016-02-06 22:16:58 -08:00
m32r_sio_reg.h
Makefile serial: mvebu-uart: initial support for Armada-3700 serial port 2016-03-07 16:11:14 -08:00
max310x.c gpio: change member .dev to .parent 2015-11-19 09:24:35 +01:00
max3100.c spi: Drop owner assignment from spi_drivers 2015-10-28 10:30:17 +09:00
mcf.c drivers/tty/serial/mcf.c: fix typo on SERIAL_MCF_CONSOLE 2015-05-06 22:26:59 +02:00
men_z135_uart.c serial/men_z135_uart: Deinline men_z135_reg_clr, save 176 bytes 2015-12-13 19:59:48 -08:00
meson_uart.c tty: serial: meson: Implement earlycon support 2016-04-30 09:26:55 -07:00
mpc52xx_uart.c tty: serial: constify psc_ops structs 2016-02-06 22:31:47 -08:00
mpsc.c TTY: serial/mpsc, remove unused fields 2016-02-06 22:16:21 -08:00
msm_serial.c tty: serial: msm: Support more bauds 2016-04-30 09:26:55 -07:00
msm_serial.h tty: serial: msm: Add RX DMA support 2015-10-04 19:15:17 +01:00
mux.c parisc: serial/mux: Convert to uart_console_device instead of open-coded 2015-10-22 15:44:28 +02:00
mvebu-uart.c drivers/tty: make serial/mvebu-uart.c explicitly non-modular 2016-04-30 09:26:55 -07:00
mxs-auart.c serial: mxs-auart: add Alphascale ASM9260 support 2016-04-30 09:26:55 -07:00
netx-serial.c
omap-serial.c Merge 4.5-rc4 into tty-next 2016-02-14 14:36:04 -08:00
pch_uart.c
pmac_zilog.c tty: constify of_device_id array 2015-03-26 22:49:10 +01:00
pmac_zilog.h
pnx8xxx_uart.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
pxa.c serial/pxa: Deinline wait_for_xmitr, save 165 bytes 2015-12-13 19:59:48 -08:00
rp2.c
sa1100.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
samsung.c serial: samsung: optimize UART rx fifo access routine 2016-03-07 16:11:14 -08:00
samsung.h serial: samsung: fix DMA mode enter condition for small FIFO sizes 2015-08-04 22:07:23 -07:00
sb1250-duart.c
sc16is7xx.c sc16is7xx: remove useless "uart_handle_cts_change" 2016-04-30 09:26:55 -07:00
sccnxp.c
serial-tegra.c serial: tegra: Add helper function for handling RX buffer 2015-10-17 21:07:57 -07:00
serial_core.c serial: core: Prevent unsafe uart port access, part 3 2016-04-30 09:26:55 -07:00
serial_ks8695.c serial: Fix ASYNC_* => UPF_* flags misuse 2016-01-28 14:17:42 -08:00
serial_mctrl_gpio.c serial: mctrl_gpio: Add missing module license 2016-03-07 16:11:14 -08:00
serial_mctrl_gpio.h serial: mctrl_gpio: Grammar s/lines GPIOs/line GPIOs/, /sets/set/ 2016-04-30 09:26:55 -07:00
serial_txx9.c
sh-sci.c serial: sh-sci: Remove redundant instances of EARLYCON_DECLARE() 2016-03-07 16:11:14 -08:00
sh-sci.h serial: sh-sci: Add more Serial Mode Register documentation 2016-02-06 22:54:55 -08:00
sirfsoc_uart.c serial: sirf: let uart's receive start in right place 2015-07-23 15:32:04 -07:00
sirfsoc_uart.h serial: sirf: let uart's receive start in right place 2015-07-23 15:32:04 -07:00
sn_console.c drivers/tty: make serial/sn_console.c driver explicitly non-modular 2015-07-23 18:27:41 -07:00
sprd_serial.c earlycon: Use common framework for earlycon declarations 2016-02-06 22:07:37 -08:00
st-asc.c tty/serial: st-asc: drop the use of IRQF_NO_SUSPEND 2015-10-04 19:11:05 +01:00
stm32-usart.c tty/serial: st-asc: drop the use of IRQF_NO_SUSPEND 2015-10-04 19:11:05 +01:00
suncore.c drivers/tty: make serial/suncore.c driver explicitly non-modular 2015-07-23 18:27:41 -07:00
sunhv.c tty/serial: Skip 'NULL' char after console break when sysrq enabled 2015-12-24 12:13:37 -05:00
sunsab.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
sunsab.h
sunsu.c serial/sunsu: Deinline wait_for_xmitr, save 165 bytes 2015-12-13 19:59:48 -08:00
sunzilog.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
sunzilog.h
tilegx.c
timbuart.c Driver core patches for 3.19-rc1 2014-12-14 16:10:09 -08:00
timbuart.h
uartlite.c Revert "serial-uartlite: Constify uartlite_be/uartlite_le" 2016-04-19 15:15:38 +09:00
ucc_uart.c QE: Move QE from arch/powerpc to drivers/soc 2015-12-22 17:12:56 -06:00
vr41xx_siu.c
vt8500_serial.c serial/vt8500_serial: Deinline wait_for_xmitr, save 165 bytes 2015-12-13 19:59:48 -08:00
xilinx_uartps.c serial: xuartps: Enable OF earlycon support 2016-03-07 16:11:14 -08:00
zs.c serial: zs: Fix a transmit lockup in console output 2016-02-06 23:13:30 -08:00
zs.h