stasc.c revision 1.3
11.3Sandvar/* $NetBSD: stasc.c,v 1.3 2024/02/08 10:30:25 andvar Exp $ */ 21.1Suwe/* 31.1Suwe * Copyright (c) 2020 Valery Ushakov 41.1Suwe * All rights reserved. 51.1Suwe * 61.1Suwe * Redistribution and use in source and binary forms, with or without 71.1Suwe * modification, are permitted provided that the following conditions 81.1Suwe * are met: 91.1Suwe * 1. Redistributions of source code must retain the above copyright 101.1Suwe * notice, this list of conditions and the following disclaimer. 111.1Suwe * 2. Redistributions in binary form must reproduce the above copyright 121.1Suwe * notice, this list of conditions and the following disclaimer in the 131.1Suwe * documentation and/or other materials provided with the distribution. 141.1Suwe * 151.1Suwe * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161.1Suwe * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171.1Suwe * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181.1Suwe * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191.1Suwe * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201.1Suwe * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211.1Suwe * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221.1Suwe * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231.1Suwe * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241.1Suwe * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251.1Suwe */ 261.1Suwe 271.1Suwe/* 281.1Suwe * STMicroelectronics ST40 Asynchronous Serial Controller 291.1Suwe */ 301.1Suwe#include <sys/cdefs.h> 311.3Sandvar__KERNEL_RCSID(0, "$NetBSD: stasc.c,v 1.3 2024/02/08 10:30:25 andvar Exp $"); 321.1Suwe 331.1Suwe#include <sys/param.h> 341.1Suwe#include <sys/systm.h> 351.1Suwe#include <sys/conf.h> 361.1Suwe#include <sys/device.h> 371.1Suwe#include <sys/kernel.h> 381.1Suwe 391.1Suwe#include <dev/cons.h> 401.1Suwe 411.1Suwe 421.1Suwe#define STM_ASC_BASE 0xfd032000 431.1Suwe 441.1Suwe#define ASC_BAUDRATE_OFFSET 0x00 451.1Suwe#define ASC_TX_BUFF_OFFSET 0x04 461.1Suwe#define ASC_RX_BUFF_OFFSET 0x08 471.1Suwe#define ASC_CTRL_OFFSET 0x0C 481.1Suwe#define ASC_INT_EN_OFFSET 0x10 491.1Suwe#define ASC_INT_STA_OFFSET 0x14 501.1Suwe#define ASC_GUARDTIME_OFFSET 0x18 511.1Suwe#define ASC_TIMEOUT_OFFSET 0x1C 521.1Suwe#define ASC_TX_RST_OFFSET 0x20 531.1Suwe#define ASC_RX_RST_OFFSET 0x24 541.1Suwe#define ASC_RETRIES_OFFSET 0x28 551.1Suwe 561.1Suwe#define ASC_TX_BUFF (*(volatile uint32_t *)(STM_ASC_BASE + ASC_TX_BUFF_OFFSET)) 571.2Suwe#define ASC_RX_BUFF (*(volatile uint32_t *)(STM_ASC_BASE + ASC_RX_BUFF_OFFSET)) 581.1Suwe#define ASC_INT_EN (*(volatile uint32_t *)(STM_ASC_BASE + ASC_INT_EN_OFFSET)) 591.1Suwe#define ASC_INT_STA (*(volatile uint32_t *)(STM_ASC_BASE + ASC_INT_STA_OFFSET)) 601.1Suwe 611.1Suwe 621.1Suwe#define ASC_CTRL_NACK_DISABLE 0x2000 631.1Suwe#define ASC_CTRL_BAUDMODE 0x1000 641.1Suwe#define ASC_CTRL_CTS_EN 0x0800 651.1Suwe#define ASC_CTRL_FIFO_EN 0x0400 661.1Suwe#define ASC_CTRL_SC_EN 0x0200 671.1Suwe#define ASC_CTRL_RX_EN 0x0100 681.1Suwe#define ASC_CTRL_RUN 0x0080 691.1Suwe#define ASC_CTRL_LOOPBACK 0x0040 701.1Suwe#define ASC_CTRL_PARITYODD 0x0020 711.1Suwe#define ASC_CTRL_STOPBITS_MASK 0x0018 721.1Suwe#define ASC_CTRL_STOPBITS_0_5 0x0000 731.1Suwe#define ASC_CTRL_STOPBITS_1_0 0x0008 741.1Suwe#define ASC_CTRL_STOPBITS_1_5 0x0010 751.1Suwe#define ASC_CTRL_STOPBITS_2_0 0x0018 761.1Suwe#define ASC_CTRL_MODE_MASK 0x0007 771.1Suwe#define ASC_CTRL_MODE_8N 0x0001 /* 8 bit */ 781.1Suwe#define ASC_CTRL_MODE_7P 0x0003 /* 7 bit + parity */ 791.1Suwe#define ASC_CTRL_MODE_9N 0x0004 /* 9 bit */ 801.1Suwe#define ASC_CTRL_MODE_8W 0x0005 /* 8 bit + wakeup */ 811.1Suwe#define ASC_CTRL_MODE_8P 0x0007 /* 8 bit + parity */ 821.1Suwe 831.1Suwe 841.1Suwe#define ASC_INT_EN_RHF 0x0100 /* ASC_INT_STA_RHF */ 851.1Suwe#define ASC_INT_EN_TOE 0x0080 /* ASC_INT_STA_TOE */ 861.1Suwe#define ASC_INT_EN_TNE 0x0040 /* ASC_INT_STA_TNE */ 871.1Suwe#define ASC_INT_EN_OE 0x0020 /* ASC_INT_STA_OE */ 881.1Suwe#define ASC_INT_EN_FE 0x0010 /* ASC_INT_STA_FE */ 891.1Suwe#define ASC_INT_EN_PE 0x0008 /* ASC_INT_STA_PE */ 901.1Suwe#define ASC_INT_EN_THE 0x0004 /* ASC_INT_STA_THE */ 911.1Suwe#define ASC_INT_EN_TE 0x0002 /* ASC_INT_STA_TE */ 921.1Suwe#define ASC_INT_EN_RBF 0x0001 /* ASC_INT_STA_RBF */ 931.1Suwe 941.1Suwe#define ASC_INT_STA_NKD 0x0400 /* Tx: NACK Data */ 951.1Suwe#define ASC_INT_STA_TF 0x0200 /* Tx: Transmitter Full */ 961.1Suwe#define ASC_INT_STA_RHF 0x0100 /* Rx: Receiver FIFO Half Full */ 971.1Suwe#define ASC_INT_STA_TOE 0x0080 /* Rx: Timeout Or Empty */ 981.1Suwe#define ASC_INT_STA_TNE 0x0040 /* Rx: Timeout Or Not Empty */ 991.1Suwe#define ASC_INT_STA_OE 0x0020 /* Rx: Overrun Error */ 1001.1Suwe#define ASC_INT_STA_FE 0x0010 /* Rx: Frame Error */ 1011.1Suwe#define ASC_INT_STA_PE 0x0008 /* Rx: Parity Error */ 1021.1Suwe#define ASC_INT_STA_THE 0x0004 /* Tx: Transmitter FIFO Half Empty */ 1031.1Suwe#define ASC_INT_STA_TE 0x0002 /* Tx: Transmitter Empty */ 1041.3Sandvar#define ASC_INT_STA_RBF 0x0001 /* Rx: Receiver Buffer Full */ 1051.1Suwe 1061.1Suwe 1071.1Suwe 1081.1Suwestruct stasc_softc { 1091.1Suwe device_t sc_dev; 1101.1Suwe}; 1111.1Suwe 1121.1Suwe 1131.1Suwestatic int stasc_match(device_t, cfdata_t, void *); 1141.1Suwestatic void stasc_attach(device_t, device_t, void *); 1151.1Suwe 1161.1SuweCFATTACH_DECL_NEW(stasc, sizeof(struct stasc_softc), 1171.1Suwe stasc_match, stasc_attach, NULL, NULL); 1181.1Suwe 1191.1Suwe 1201.1Suwe/* console */ 1211.1Suwecons_decl(stasc_) 1221.1Suwe 1231.1Suwe/* assign to cn_tab after cleaning bss to get printf early for the cpu setup */ 1241.1Suwestruct consdev stasc_earlycons = cons_init(stasc_); 1251.1Suwe 1261.1Suweextern struct cfdriver stasc_cd; 1271.1Suwe 1281.1Suweconst struct cdevsw stasc_cdevsw = { 1291.1Suwe .d_open = noopen, 1301.1Suwe .d_close = noclose, 1311.1Suwe .d_read = noread, 1321.1Suwe .d_write = nowrite, 1331.1Suwe .d_ioctl = noioctl, 1341.1Suwe .d_stop = nostop, 1351.1Suwe .d_tty = notty, 1361.1Suwe .d_poll = nopoll, 1371.1Suwe .d_mmap = nommap, 1381.1Suwe .d_kqfilter = nokqfilter, 1391.1Suwe .d_discard = nodiscard, 1401.1Suwe .d_flag = D_TTY 1411.1Suwe}; 1421.1Suwe 1431.1Suwe 1441.1Suwe 1451.1Suwestatic int 1461.1Suwestasc_match(device_t parent, cfdata_t cfp, void *aux) 1471.1Suwe{ 1481.1Suwe 1491.1Suwe if (strcmp(cfp->cf_name, "stasc") != 0) 1501.1Suwe return 0; 1511.1Suwe 1521.1Suwe return 0; /* just stub it out for now */ 1531.1Suwe} 1541.1Suwe 1551.1Suwe 1561.1Suwestatic void 1571.1Suwestasc_attach(device_t parent, device_t self, void *aux) 1581.1Suwe{ 1591.1Suwe struct stasc_softc *sc; 1601.1Suwe 1611.1Suwe sc = device_private(self); 1621.1Suwe sc->sc_dev = self; 1631.1Suwe 1641.1Suwe aprint_normal("\n"); 1651.1Suwe} 1661.1Suwe 1671.1Suwe 1681.1Suwevoid 1691.1Suwestasc_cnprobe(struct consdev *cp) 1701.1Suwe{ 1711.1Suwe 1721.1Suwe cp->cn_pri = CN_NORMAL; 1731.1Suwe} 1741.1Suwe 1751.1Suwe 1761.1Suwevoid 1771.1Suwestasc_cninit(struct consdev *cp) 1781.1Suwe{ 1791.1Suwe 1801.1Suwe return; 1811.1Suwe} 1821.1Suwe 1831.1Suwe 1841.1Suweint 1851.1Suwestasc_cngetc(dev_t dev) 1861.1Suwe{ 1871.2Suwe int s = splserial(); 1881.2Suwe uint32_t status; 1891.2Suwe int c; 1901.2Suwe 1911.2Suwe /* don't block if Rx buffer is empty */ 1921.2Suwe status = ASC_INT_STA; 1931.2Suwe if (!ISSET(status, ASC_INT_STA_RBF)) { 1941.2Suwe splx(s); 1951.2Suwe return -1; 1961.2Suwe } 1971.2Suwe 1981.2Suwe /* can read the character now */ 1991.2Suwe c = ASC_RX_BUFF; 2001.2Suwe splx(s); 2011.2Suwe return (unsigned char)c; 2021.1Suwe} 2031.1Suwe 2041.1Suwe 2051.1Suwevoid 2061.1Suwestasc_cnputc(dev_t dev, int c) 2071.1Suwe{ 2081.2Suwe int s = splserial(); 2091.2Suwe uint32_t timo, status; 2101.1Suwe 2111.2Suwe /* wait for Tx Full to become clear */ 2121.2Suwe timo = 150000; 2131.1Suwe do { 2141.1Suwe status = ASC_INT_STA; 2151.2Suwe } while (ISSET(status, ASC_INT_STA_TF) && --timo); 2161.1Suwe 2171.1Suwe /* can write the character now */ 2181.1Suwe ASC_TX_BUFF = c; 2191.2Suwe splx(s); 2201.1Suwe} 2211.1Suwe 2221.1Suwe 2231.1Suwevoid 2241.1Suwestasc_cnpollc(dev_t dev, int on) 2251.1Suwe{ 2261.1Suwe 2271.1Suwe return; 2281.1Suwe} 229