139e661bcSEtienne Carriere /* 239e661bcSEtienne Carriere * Copyright (c) 2017, Linaro Limited 339e661bcSEtienne Carriere * All rights reserved. 439e661bcSEtienne Carriere * 539e661bcSEtienne Carriere * Redistribution and use in source and binary forms, with or without 639e661bcSEtienne Carriere * modification, are permitted provided that the following conditions are met: 739e661bcSEtienne Carriere * 839e661bcSEtienne Carriere * 1. Redistributions of source code must retain the above copyright notice, 939e661bcSEtienne Carriere * this list of conditions and the following disclaimer. 1039e661bcSEtienne Carriere * 1139e661bcSEtienne Carriere * 2. Redistributions in binary form must reproduce the above copyright notice, 1239e661bcSEtienne Carriere * this list of conditions and the following disclaimer in the documentation 1339e661bcSEtienne Carriere * and/or other materials provided with the distribution. 1439e661bcSEtienne Carriere * 1539e661bcSEtienne Carriere * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1639e661bcSEtienne Carriere * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1739e661bcSEtienne Carriere * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1839e661bcSEtienne Carriere * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 1939e661bcSEtienne Carriere * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2039e661bcSEtienne Carriere * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2139e661bcSEtienne Carriere * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2239e661bcSEtienne Carriere * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2339e661bcSEtienne Carriere * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2439e661bcSEtienne Carriere * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2539e661bcSEtienne Carriere * POSSIBILITY OF SUCH DAMAGE. 2639e661bcSEtienne Carriere */ 2739e661bcSEtienne Carriere #include <drivers/stih_asc.h> 2839e661bcSEtienne Carriere #include <io.h> 29*0cb71d15SEtienne Carriere #include <keep.h> 3039e661bcSEtienne Carriere #include <util.h> 3139e661bcSEtienne Carriere 3239e661bcSEtienne Carriere #define ASC_BAUDRATE 0x00 3339e661bcSEtienne Carriere #define ASC_TXBUFFER 0x04 3439e661bcSEtienne Carriere #define ASC_STATUS 0x14 3539e661bcSEtienne Carriere 3639e661bcSEtienne Carriere #define ASC_STATUS_TX_EMPTY BIT(1) 3739e661bcSEtienne Carriere #define ASC_STATUS_TX_HALF_EMPTY BIT(2) 3839e661bcSEtienne Carriere 39*0cb71d15SEtienne Carriere static vaddr_t chip_to_base(struct serial_chip *chip) 4039e661bcSEtienne Carriere { 41*0cb71d15SEtienne Carriere struct stih_asc_pd *pd = 42*0cb71d15SEtienne Carriere container_of(chip, struct stih_asc_pd, chip); 43*0cb71d15SEtienne Carriere 44*0cb71d15SEtienne Carriere return io_pa_or_va(&pd->base); 45*0cb71d15SEtienne Carriere } 46*0cb71d15SEtienne Carriere 47*0cb71d15SEtienne Carriere static void stih_asc_flush(struct serial_chip *chip) 48*0cb71d15SEtienne Carriere { 49*0cb71d15SEtienne Carriere vaddr_t base = chip_to_base(chip); 50*0cb71d15SEtienne Carriere 5139e661bcSEtienne Carriere while (!(read32(base + ASC_STATUS) & ASC_STATUS_TX_EMPTY)) 5239e661bcSEtienne Carriere ; 5339e661bcSEtienne Carriere } 5439e661bcSEtienne Carriere 55*0cb71d15SEtienne Carriere static void stih_asc_putc(struct serial_chip *chip, int ch) 5639e661bcSEtienne Carriere { 57*0cb71d15SEtienne Carriere vaddr_t base = chip_to_base(chip); 58*0cb71d15SEtienne Carriere 5939e661bcSEtienne Carriere while (!(read32(base + ASC_STATUS) & ASC_STATUS_TX_HALF_EMPTY)) 6039e661bcSEtienne Carriere ; 6139e661bcSEtienne Carriere 6239e661bcSEtienne Carriere write32(ch, base + ASC_TXBUFFER); 6339e661bcSEtienne Carriere } 6439e661bcSEtienne Carriere 65*0cb71d15SEtienne Carriere static const struct serial_ops stih_asc_ops = { 66*0cb71d15SEtienne Carriere .flush = stih_asc_flush, 67*0cb71d15SEtienne Carriere .putc = stih_asc_putc, 68*0cb71d15SEtienne Carriere }; 69*0cb71d15SEtienne Carriere KEEP_PAGER(stih_asc_ops); 70*0cb71d15SEtienne Carriere 71*0cb71d15SEtienne Carriere void stih_asc_init(struct stih_asc_pd *pd, vaddr_t base) 7239e661bcSEtienne Carriere { 73*0cb71d15SEtienne Carriere pd->base.pa = base; 74*0cb71d15SEtienne Carriere pd->chip.ops = &stih_asc_ops; 7539e661bcSEtienne Carriere } 76