11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
239e661bcSEtienne Carriere /*
339e661bcSEtienne Carriere * Copyright (c) 2017, Linaro Limited
439e661bcSEtienne Carriere */
539e661bcSEtienne Carriere #include <drivers/stih_asc.h>
639e661bcSEtienne Carriere #include <io.h>
70cb71d15SEtienne Carriere #include <keep.h>
839e661bcSEtienne Carriere #include <util.h>
939e661bcSEtienne Carriere
1039e661bcSEtienne Carriere #define ASC_BAUDRATE 0x00
1139e661bcSEtienne Carriere #define ASC_TXBUFFER 0x04
1239e661bcSEtienne Carriere #define ASC_STATUS 0x14
1339e661bcSEtienne Carriere
1439e661bcSEtienne Carriere #define ASC_STATUS_TX_EMPTY BIT(1)
1539e661bcSEtienne Carriere #define ASC_STATUS_TX_HALF_EMPTY BIT(2)
1639e661bcSEtienne Carriere
chip_to_base(struct serial_chip * chip)170cb71d15SEtienne Carriere static vaddr_t chip_to_base(struct serial_chip *chip)
1839e661bcSEtienne Carriere {
190cb71d15SEtienne Carriere struct stih_asc_pd *pd =
200cb71d15SEtienne Carriere container_of(chip, struct stih_asc_pd, chip);
210cb71d15SEtienne Carriere
22*c2e4eb43SAnton Rybakov return io_pa_or_va(&pd->base, STIH_ASC_REG_SIZE);
230cb71d15SEtienne Carriere }
240cb71d15SEtienne Carriere
stih_asc_flush(struct serial_chip * chip)250cb71d15SEtienne Carriere static void stih_asc_flush(struct serial_chip *chip)
260cb71d15SEtienne Carriere {
270cb71d15SEtienne Carriere vaddr_t base = chip_to_base(chip);
280cb71d15SEtienne Carriere
29918bb3a5SEtienne Carriere while (!(io_read32(base + ASC_STATUS) & ASC_STATUS_TX_EMPTY))
3039e661bcSEtienne Carriere ;
3139e661bcSEtienne Carriere }
3239e661bcSEtienne Carriere
stih_asc_putc(struct serial_chip * chip,int ch)330cb71d15SEtienne Carriere static void stih_asc_putc(struct serial_chip *chip, int ch)
3439e661bcSEtienne Carriere {
350cb71d15SEtienne Carriere vaddr_t base = chip_to_base(chip);
360cb71d15SEtienne Carriere
37918bb3a5SEtienne Carriere while (!(io_read32(base + ASC_STATUS) & ASC_STATUS_TX_HALF_EMPTY))
3839e661bcSEtienne Carriere ;
3939e661bcSEtienne Carriere
40918bb3a5SEtienne Carriere io_write32(base + ASC_TXBUFFER, ch);
4139e661bcSEtienne Carriere }
4239e661bcSEtienne Carriere
430cb71d15SEtienne Carriere static const struct serial_ops stih_asc_ops = {
440cb71d15SEtienne Carriere .flush = stih_asc_flush,
450cb71d15SEtienne Carriere .putc = stih_asc_putc,
460cb71d15SEtienne Carriere };
473639b55fSJerome Forissier DECLARE_KEEP_PAGER(stih_asc_ops);
480cb71d15SEtienne Carriere
stih_asc_init(struct stih_asc_pd * pd,vaddr_t base)490cb71d15SEtienne Carriere void stih_asc_init(struct stih_asc_pd *pd, vaddr_t base)
5039e661bcSEtienne Carriere {
510cb71d15SEtienne Carriere pd->base.pa = base;
520cb71d15SEtienne Carriere pd->chip.ops = &stih_asc_ops;
5339e661bcSEtienne Carriere }
54