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 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 220cb71d15SEtienne Carriere return io_pa_or_va(&pd->base); 230cb71d15SEtienne Carriere } 240cb71d15SEtienne Carriere 250cb71d15SEtienne Carriere static void stih_asc_flush(struct serial_chip *chip) 260cb71d15SEtienne Carriere { 270cb71d15SEtienne Carriere vaddr_t base = chip_to_base(chip); 280cb71d15SEtienne Carriere 29*918bb3a5SEtienne Carriere while (!(io_read32(base + ASC_STATUS) & ASC_STATUS_TX_EMPTY)) 3039e661bcSEtienne Carriere ; 3139e661bcSEtienne Carriere } 3239e661bcSEtienne Carriere 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 37*918bb3a5SEtienne Carriere while (!(io_read32(base + ASC_STATUS) & ASC_STATUS_TX_HALF_EMPTY)) 3839e661bcSEtienne Carriere ; 3939e661bcSEtienne Carriere 40*918bb3a5SEtienne 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 }; 470cb71d15SEtienne Carriere KEEP_PAGER(stih_asc_ops); 480cb71d15SEtienne Carriere 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