1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017, Linaro Limited
4  */
5 #include <drivers/stih_asc.h>
6 #include <io.h>
7 #include <keep.h>
8 #include <util.h>
9 
10 #define ASC_BAUDRATE		0x00
11 #define ASC_TXBUFFER		0x04
12 #define ASC_STATUS		0x14
13 
14 #define ASC_STATUS_TX_EMPTY		BIT(1)
15 #define ASC_STATUS_TX_HALF_EMPTY	BIT(2)
16 
chip_to_base(struct serial_chip * chip)17 static vaddr_t chip_to_base(struct serial_chip *chip)
18 {
19 	struct stih_asc_pd *pd =
20 		container_of(chip, struct stih_asc_pd, chip);
21 
22 	return io_pa_or_va(&pd->base, STIH_ASC_REG_SIZE);
23 }
24 
stih_asc_flush(struct serial_chip * chip)25 static void stih_asc_flush(struct serial_chip *chip)
26 {
27 	vaddr_t base = chip_to_base(chip);
28 
29 	while (!(io_read32(base + ASC_STATUS) & ASC_STATUS_TX_EMPTY))
30 		;
31 }
32 
stih_asc_putc(struct serial_chip * chip,int ch)33 static void stih_asc_putc(struct serial_chip *chip, int ch)
34 {
35 	vaddr_t base = chip_to_base(chip);
36 
37 	while (!(io_read32(base + ASC_STATUS) & ASC_STATUS_TX_HALF_EMPTY))
38 		;
39 
40 	io_write32(base + ASC_TXBUFFER, ch);
41 }
42 
43 static const struct serial_ops stih_asc_ops = {
44 	.flush = stih_asc_flush,
45 	.putc = stih_asc_putc,
46 };
47 DECLARE_KEEP_PAGER(stih_asc_ops);
48 
stih_asc_init(struct stih_asc_pd * pd,vaddr_t base)49 void stih_asc_init(struct stih_asc_pd *pd, vaddr_t base)
50 {
51 	pd->base.pa = base;
52 	pd->chip.ops = &stih_asc_ops;
53 }
54