blob: 4b528e4529266af30500b824b477d85c794b7918 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Andy Shevchenkoc65a7fe2017-02-28 14:04:10 +02002/*
3 * Copyright (c) 2017 Intel Corporation
Andy Shevchenkoc65a7fe2017-02-28 14:04:10 +02004 */
5
Andy Shevchenkoc65a7fe2017-02-28 14:04:10 +02006#include <dm.h>
7#include <ns16550.h>
8#include <serial.h>
9
10/*
11 * The UART clock is calculated as
12 *
13 * UART clock = XTAL * UART_MUL / UART_DIV
14 *
15 * The baudrate is calculated as
16 *
17 * baud rate = UART clock / UART_PS / DLAB
18 */
19#define UART_PS 0x30
20#define UART_MUL 0x34
21#define UART_DIV 0x38
22
Simon Glassb75b15b2020-12-03 16:55:23 -070023static void mid_writel(struct ns16550_plat *plat, int offset, int value)
Andy Shevchenkoc65a7fe2017-02-28 14:04:10 +020024{
25 unsigned char *addr;
26
27 offset *= 1 << plat->reg_shift;
28 addr = (unsigned char *)plat->base + offset;
29
30 writel(value, addr + plat->reg_offset);
31}
32
33static int mid_serial_probe(struct udevice *dev)
34{
Simon Glassb75b15b2020-12-03 16:55:23 -070035 struct ns16550_plat *plat = dev_get_plat(dev);
Andy Shevchenkoc65a7fe2017-02-28 14:04:10 +020036
37 /*
38 * Initialize fractional divider correctly for Intel Edison
39 * platform.
40 *
41 * For backward compatibility we have to set initial DLAB value
42 * to 16 and speed to 115200 baud, where initial frequency is
43 * 29491200Hz, and XTAL frequency is 38.4MHz.
44 */
45 mid_writel(plat, UART_MUL, 96);
46 mid_writel(plat, UART_DIV, 125);
47 mid_writel(plat, UART_PS, 16);
48
49 return ns16550_serial_probe(dev);
50}
51
52static const struct udevice_id mid_serial_ids[] = {
53 { .compatible = "intel,mid-uart" },
54 {}
55};
56
57U_BOOT_DRIVER(serial_intel_mid) = {
58 .name = "serial_intel_mid",
59 .id = UCLASS_SERIAL,
60 .of_match = mid_serial_ids,
Simon Glassaad29ae2020-12-03 16:55:21 -070061 .of_to_plat = ns16550_serial_of_to_plat,
Simon Glassb75b15b2020-12-03 16:55:23 -070062 .plat_auto = sizeof(struct ns16550_plat),
Simon Glass119e7ef2020-12-22 19:30:18 -070063 .priv_auto = sizeof(struct ns16550),
Andy Shevchenkoc65a7fe2017-02-28 14:04:10 +020064 .probe = mid_serial_probe,
65 .ops = &ns16550_serial_ops,
Andy Shevchenkoc65a7fe2017-02-28 14:04:10 +020066};