Commit Diff


commit - f7cc1b3ab133d571912de730beed9942af5cc871
commit + 874f520e5a368da66ade702f31c53d8109692056
blob - e484c07148ca354c1c4124f602225a0527aac060
blob + 301eb3b8729d953d26a8cff29f7ca3178f805dfd
--- capsule/squat/reports/0.0.2.gmi
+++ capsule/squat/reports/0.0.2.gmi
@@ -210,3 +210,87 @@ aarch64-linux-gnu-objdump -d spl/u-boot-spl | less
    16338:       a8c27bfd        ldp     x29, x30, [sp], #32
    1633c:       d65f03c0        ret
 ```
+
+#define SUNXI_UART0_BASE              0x01c28000
+
+drivers/serial/serial_ns16550.c
+```
+/* Multi serial device functions */
+#define DECLARE_ESERIAL_FUNCTIONS(port) \
+    static int  eserial##port##_init(void) \
+    { \
+        int clock_divisor; \
+        clock_divisor = ns16550_calc_divisor(serial_ports[port-1], \
+                CONFIG_SYS_NS16550_CLK, gd->baudrate); \
+        ns16550_init(serial_ports[port - 1], clock_divisor); \
+        return 0 ; \
+    } \
+```
+
+include/configs/sunxi-common.h
+```
+#define CONFIG_SYS_NS16550_CLK                24000000
+```
+
+```
+00000000000163bc <ns16550_calc_divisor>:
+   163bc:       531c6c40        lsl     w0, w2, #4
+   163c0:       531d6c42        ubfiz   w2, w2, #3, #28
+   163c4:       0b010042        add     w2, w2, w1
+   163c8:       1ac00840        udiv    w0, w2, w0
+   163cc:       d65f03c0        ret
+```
+
+drivers/serial/ns16550.c
+```
+int ns16550_calc_divisor(struct ns16550 *port, int clock, int baudrate)
+{
+    const unsigned int mode_x_div = 16;
+
+    return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate);
+}
+```
+
+include/linux/kernel.h
+```
+/*
+ * Divide positive or negative dividend by positive divisor and round
+ * to closest integer. Result is undefined for negative divisors and
+ * for negative dividends if the divisor variable type is unsigned.
+ */
+#define DIV_ROUND_CLOSEST(x, divisor)(          \
+{                           \
+    typeof(x) __x = x;              \
+    typeof(divisor) __d = divisor;          \
+    (((typeof(x))-1) > 0 ||             \
+     ((typeof(divisor))-1) > 0 || (__x) > 0) ?  \
+        (((__x) + ((__d) / 2)) / (__d)) :   \
+        (((__x) - ((__d) / 2)) / (__d));    \
+}                           \
+)
+```
+
+24000000 / (16 * 115200) ~= 13
+
+```
+00000000000163d0 <ns16550_init>:
+   163d0:       39405002        ldrb    w2, [x0, #20]
+   163d4:       12001c42        and     w2, w2, #0xff
+   163d8:       d5033fbf        dmb     sy
+   163dc:       3637ffa2        tbz     w2, #6, 163d0 <ns16550_init>    // while (!(serial_in(&com_port->lsr) & UART_LSR_TEMT))
+
+   163e0:       d5033fbf        dmb     sy
+   163e4:       3900101f        strb    wzr, [x0, #4]                   // IER
+   163e8:       d5033fbf        dmb     sy
+   163ec:       52800062        mov     w2, #0x3
+   163f0:       39004002        strb    w2, [x0, #16]                   // MCR
+   163f4:       d5033fbf        dmb     sy
+   163f8:       528000e3        mov     w3, #0x7
+   163fc:       39002003        strb    w3, [x0, #8]                    // FCR
+   16400:       d5033fbf        dmb     sy
+   16404:       39003002        strb    w2, [x0, #12]                   // LCR
+   16408:       3100043f        cmn     w1, #0x1
+   1640c:       54000040        b.eq    16414 <ns16550_init+0x44>  // b.none
+   16410:       17ffffda        b       16378 <ns16550_setbrg>
+   16414:       d65f03c0        ret
+```