LCOV - code coverage report
Current view: top level - drivers/tty/serial/8250 - 8250_mid.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 1 159 0.6 %
Date: 2022-04-01 14:58:12 Functions: 1 12 8.3 %
Branches: 0 194 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * 8250_mid.c - Driver for UART on Intel Penwell and various other Intel SOCs
       4                 :            :  *
       5                 :            :  * Copyright (C) 2015 Intel Corporation
       6                 :            :  * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
       7                 :            :  */
       8                 :            : 
       9                 :            : #include <linux/bitops.h>
      10                 :            : #include <linux/module.h>
      11                 :            : #include <linux/pci.h>
      12                 :            : #include <linux/rational.h>
      13                 :            : 
      14                 :            : #include <linux/dma/hsu.h>
      15                 :            : #include <linux/8250_pci.h>
      16                 :            : 
      17                 :            : #include "8250.h"
      18                 :            : 
      19                 :            : #define PCI_DEVICE_ID_INTEL_PNW_UART1   0x081b
      20                 :            : #define PCI_DEVICE_ID_INTEL_PNW_UART2   0x081c
      21                 :            : #define PCI_DEVICE_ID_INTEL_PNW_UART3   0x081d
      22                 :            : #define PCI_DEVICE_ID_INTEL_TNG_UART    0x1191
      23                 :            : #define PCI_DEVICE_ID_INTEL_CDF_UART    0x18d8
      24                 :            : #define PCI_DEVICE_ID_INTEL_DNV_UART    0x19d8
      25                 :            : 
      26                 :            : /* Intel MID Specific registers */
      27                 :            : #define INTEL_MID_UART_FISR             0x08
      28                 :            : #define INTEL_MID_UART_PS               0x30
      29                 :            : #define INTEL_MID_UART_MUL              0x34
      30                 :            : #define INTEL_MID_UART_DIV              0x38
      31                 :            : 
      32                 :            : struct mid8250;
      33                 :            : 
      34                 :            : struct mid8250_board {
      35                 :            :         unsigned int flags;
      36                 :            :         unsigned long freq;
      37                 :            :         unsigned int base_baud;
      38                 :            :         int (*setup)(struct mid8250 *, struct uart_port *p);
      39                 :            :         void (*exit)(struct mid8250 *);
      40                 :            : };
      41                 :            : 
      42                 :            : struct mid8250 {
      43                 :            :         int line;
      44                 :            :         int dma_index;
      45                 :            :         struct pci_dev *dma_dev;
      46                 :            :         struct uart_8250_dma dma;
      47                 :            :         struct mid8250_board *board;
      48                 :            :         struct hsu_dma_chip dma_chip;
      49                 :            : };
      50                 :            : 
      51                 :            : /*****************************************************************************/
      52                 :            : 
      53                 :          0 : static int pnw_setup(struct mid8250 *mid, struct uart_port *p)
      54                 :            : {
      55                 :          0 :         struct pci_dev *pdev = to_pci_dev(p->dev);
      56                 :            : 
      57   [ #  #  #  # ]:          0 :         switch (pdev->device) {
      58                 :          0 :         case PCI_DEVICE_ID_INTEL_PNW_UART1:
      59                 :          0 :                 mid->dma_index = 0;
      60                 :          0 :                 break;
      61                 :          0 :         case PCI_DEVICE_ID_INTEL_PNW_UART2:
      62                 :          0 :                 mid->dma_index = 1;
      63                 :          0 :                 break;
      64                 :          0 :         case PCI_DEVICE_ID_INTEL_PNW_UART3:
      65                 :          0 :                 mid->dma_index = 2;
      66                 :          0 :                 break;
      67                 :            :         default:
      68                 :            :                 return -EINVAL;
      69                 :            :         }
      70                 :            : 
      71                 :          0 :         mid->dma_dev = pci_get_slot(pdev->bus,
      72                 :          0 :                                     PCI_DEVFN(PCI_SLOT(pdev->devfn), 3));
      73                 :          0 :         return 0;
      74                 :            : }
      75                 :            : 
      76                 :          0 : static int tng_handle_irq(struct uart_port *p)
      77                 :            : {
      78                 :          0 :         struct mid8250 *mid = p->private_data;
      79                 :          0 :         struct uart_8250_port *up = up_to_u8250p(p);
      80                 :          0 :         struct hsu_dma_chip *chip;
      81                 :          0 :         u32 status;
      82                 :          0 :         int ret = 0;
      83                 :          0 :         int err;
      84                 :            : 
      85                 :          0 :         chip = pci_get_drvdata(mid->dma_dev);
      86                 :            : 
      87                 :            :         /* Rx DMA */
      88                 :          0 :         err = hsu_dma_get_status(chip, mid->dma_index * 2 + 1, &status);
      89         [ #  # ]:          0 :         if (err > 0) {
      90                 :          0 :                 serial8250_rx_dma_flush(up);
      91                 :          0 :                 ret |= 1;
      92         [ #  # ]:          0 :         } else if (err == 0)
      93                 :          0 :                 ret |= hsu_dma_do_irq(chip, mid->dma_index * 2 + 1, status);
      94                 :            : 
      95                 :            :         /* Tx DMA */
      96                 :          0 :         err = hsu_dma_get_status(chip, mid->dma_index * 2, &status);
      97         [ #  # ]:          0 :         if (err > 0)
      98                 :          0 :                 ret |= 1;
      99         [ #  # ]:          0 :         else if (err == 0)
     100                 :          0 :                 ret |= hsu_dma_do_irq(chip, mid->dma_index * 2, status);
     101                 :            : 
     102                 :            :         /* UART */
     103                 :          0 :         ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
     104                 :          0 :         return IRQ_RETVAL(ret);
     105                 :            : }
     106                 :            : 
     107                 :          0 : static int tng_setup(struct mid8250 *mid, struct uart_port *p)
     108                 :            : {
     109                 :          0 :         struct pci_dev *pdev = to_pci_dev(p->dev);
     110                 :          0 :         int index = PCI_FUNC(pdev->devfn);
     111                 :            : 
     112                 :            :         /*
     113                 :            :          * Device 0000:00:04.0 is not a real HSU port. It provides a global
     114                 :            :          * register set for all HSU ports, although it has the same PCI ID.
     115                 :            :          * Skip it here.
     116                 :            :          */
     117         [ #  # ]:          0 :         if (index-- == 0)
     118                 :            :                 return -ENODEV;
     119                 :            : 
     120                 :          0 :         mid->dma_index = index;
     121                 :          0 :         mid->dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(5, 0));
     122                 :            : 
     123                 :          0 :         p->handle_irq = tng_handle_irq;
     124                 :          0 :         return 0;
     125                 :            : }
     126                 :            : 
     127                 :          0 : static int dnv_handle_irq(struct uart_port *p)
     128                 :            : {
     129                 :          0 :         struct mid8250 *mid = p->private_data;
     130                 :          0 :         struct uart_8250_port *up = up_to_u8250p(p);
     131                 :          0 :         unsigned int fisr = serial_port_in(p, INTEL_MID_UART_FISR);
     132                 :          0 :         u32 status;
     133                 :          0 :         int ret = 0;
     134                 :          0 :         int err;
     135                 :            : 
     136         [ #  # ]:          0 :         if (fisr & BIT(2)) {
     137                 :          0 :                 err = hsu_dma_get_status(&mid->dma_chip, 1, &status);
     138         [ #  # ]:          0 :                 if (err > 0) {
     139                 :          0 :                         serial8250_rx_dma_flush(up);
     140                 :          0 :                         ret |= 1;
     141         [ #  # ]:          0 :                 } else if (err == 0)
     142                 :          0 :                         ret |= hsu_dma_do_irq(&mid->dma_chip, 1, status);
     143                 :            :         }
     144         [ #  # ]:          0 :         if (fisr & BIT(1)) {
     145                 :          0 :                 err = hsu_dma_get_status(&mid->dma_chip, 0, &status);
     146         [ #  # ]:          0 :                 if (err > 0)
     147                 :          0 :                         ret |= 1;
     148         [ #  # ]:          0 :                 else if (err == 0)
     149                 :          0 :                         ret |= hsu_dma_do_irq(&mid->dma_chip, 0, status);
     150                 :            :         }
     151         [ #  # ]:          0 :         if (fisr & BIT(0))
     152                 :          0 :                 ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
     153                 :          0 :         return IRQ_RETVAL(ret);
     154                 :            : }
     155                 :            : 
     156                 :            : #define DNV_DMA_CHAN_OFFSET 0x80
     157                 :            : 
     158                 :          0 : static int dnv_setup(struct mid8250 *mid, struct uart_port *p)
     159                 :            : {
     160                 :          0 :         struct hsu_dma_chip *chip = &mid->dma_chip;
     161                 :          0 :         struct pci_dev *pdev = to_pci_dev(p->dev);
     162                 :          0 :         unsigned int bar = FL_GET_BASE(mid->board->flags);
     163                 :          0 :         int ret;
     164                 :            : 
     165                 :          0 :         pci_set_master(pdev);
     166                 :            : 
     167                 :          0 :         ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
     168         [ #  # ]:          0 :         if (ret < 0)
     169                 :            :                 return ret;
     170                 :            : 
     171                 :          0 :         p->irq = pci_irq_vector(pdev, 0);
     172                 :            : 
     173                 :          0 :         chip->dev = &pdev->dev;
     174                 :          0 :         chip->irq = pci_irq_vector(pdev, 0);
     175                 :          0 :         chip->regs = p->membase;
     176   [ #  #  #  # ]:          0 :         chip->length = pci_resource_len(pdev, bar);
     177                 :          0 :         chip->offset = DNV_DMA_CHAN_OFFSET;
     178                 :            : 
     179                 :            :         /* Falling back to PIO mode if DMA probing fails */
     180                 :          0 :         ret = hsu_dma_probe(chip);
     181         [ #  # ]:          0 :         if (ret)
     182                 :            :                 return 0;
     183                 :            : 
     184                 :          0 :         mid->dma_dev = pdev;
     185                 :            : 
     186                 :          0 :         p->handle_irq = dnv_handle_irq;
     187                 :          0 :         return 0;
     188                 :            : }
     189                 :            : 
     190                 :          0 : static void dnv_exit(struct mid8250 *mid)
     191                 :            : {
     192         [ #  # ]:          0 :         if (!mid->dma_dev)
     193                 :            :                 return;
     194                 :          0 :         hsu_dma_remove(&mid->dma_chip);
     195                 :            : }
     196                 :            : 
     197                 :            : /*****************************************************************************/
     198                 :            : 
     199                 :          0 : static void mid8250_set_termios(struct uart_port *p,
     200                 :            :                                 struct ktermios *termios,
     201                 :            :                                 struct ktermios *old)
     202                 :            : {
     203                 :          0 :         unsigned int baud = tty_termios_baud_rate(termios);
     204                 :          0 :         struct mid8250 *mid = p->private_data;
     205                 :          0 :         unsigned short ps = 16;
     206                 :          0 :         unsigned long fuart = baud * ps;
     207                 :          0 :         unsigned long w = BIT(24) - 1;
     208                 :          0 :         unsigned long mul, div;
     209                 :            : 
     210                 :            :         /* Gracefully handle the B0 case: fall back to B9600 */
     211         [ #  # ]:          0 :         fuart = fuart ? fuart : 9600 * 16;
     212                 :            : 
     213         [ #  # ]:          0 :         if (mid->board->freq < fuart) {
     214                 :            :                 /* Find prescaler value that satisfies Fuart < Fref */
     215         [ #  # ]:          0 :                 if (mid->board->freq > baud)
     216                 :          0 :                         ps = mid->board->freq / baud;     /* baud rate too high */
     217                 :            :                 else
     218                 :            :                         ps = 1;                         /* PLL case */
     219                 :          0 :                 fuart = baud * ps;
     220                 :            :         } else {
     221                 :            :                 /* Get Fuart closer to Fref */
     222   [ #  #  #  #  :          0 :                 fuart *= rounddown_pow_of_two(mid->board->freq / fuart);
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     223                 :            :         }
     224                 :            : 
     225                 :          0 :         rational_best_approximation(fuart, mid->board->freq, w, w, &mul, &div);
     226                 :          0 :         p->uartclk = fuart * 16 / ps;                /* core uses ps = 16 always */
     227                 :            : 
     228                 :          0 :         writel(ps, p->membase + INTEL_MID_UART_PS);          /* set PS */
     229                 :          0 :         writel(mul, p->membase + INTEL_MID_UART_MUL);                /* set MUL */
     230                 :          0 :         writel(div, p->membase + INTEL_MID_UART_DIV);
     231                 :            : 
     232                 :          0 :         serial8250_do_set_termios(p, termios, old);
     233                 :          0 : }
     234                 :            : 
     235                 :          0 : static bool mid8250_dma_filter(struct dma_chan *chan, void *param)
     236                 :            : {
     237                 :          0 :         struct hsu_dma_slave *s = param;
     238                 :            : 
     239   [ #  #  #  # ]:          0 :         if (s->dma_dev != chan->device->dev || s->chan_id != chan->chan_id)
     240                 :            :                 return false;
     241                 :            : 
     242                 :          0 :         chan->private = s;
     243                 :          0 :         return true;
     244                 :            : }
     245                 :            : 
     246                 :            : static int mid8250_dma_setup(struct mid8250 *mid, struct uart_8250_port *port)
     247                 :            : {
     248                 :            :         struct uart_8250_dma *dma = &mid->dma;
     249                 :            :         struct device *dev = port->port.dev;
     250                 :            :         struct hsu_dma_slave *rx_param;
     251                 :            :         struct hsu_dma_slave *tx_param;
     252                 :            : 
     253                 :            :         if (!mid->dma_dev)
     254                 :            :                 return 0;
     255                 :            : 
     256                 :            :         rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL);
     257                 :            :         if (!rx_param)
     258                 :            :                 return -ENOMEM;
     259                 :            : 
     260                 :            :         tx_param = devm_kzalloc(dev, sizeof(*tx_param), GFP_KERNEL);
     261                 :            :         if (!tx_param)
     262                 :            :                 return -ENOMEM;
     263                 :            : 
     264                 :            :         rx_param->chan_id = mid->dma_index * 2 + 1;
     265                 :            :         tx_param->chan_id = mid->dma_index * 2;
     266                 :            : 
     267                 :            :         dma->rxconf.src_maxburst = 64;
     268                 :            :         dma->txconf.dst_maxburst = 64;
     269                 :            : 
     270                 :            :         rx_param->dma_dev = &mid->dma_dev->dev;
     271                 :            :         tx_param->dma_dev = &mid->dma_dev->dev;
     272                 :            : 
     273                 :            :         dma->fn = mid8250_dma_filter;
     274                 :            :         dma->rx_param = rx_param;
     275                 :            :         dma->tx_param = tx_param;
     276                 :            : 
     277                 :            :         port->dma = dma;
     278                 :            :         return 0;
     279                 :            : }
     280                 :            : 
     281                 :          0 : static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
     282                 :            : {
     283                 :          0 :         struct uart_8250_port uart;
     284                 :          0 :         struct mid8250 *mid;
     285                 :          0 :         unsigned int bar;
     286                 :          0 :         int ret;
     287                 :            : 
     288                 :          0 :         ret = pcim_enable_device(pdev);
     289         [ #  # ]:          0 :         if (ret)
     290                 :            :                 return ret;
     291                 :            : 
     292                 :          0 :         mid = devm_kzalloc(&pdev->dev, sizeof(*mid), GFP_KERNEL);
     293         [ #  # ]:          0 :         if (!mid)
     294                 :            :                 return -ENOMEM;
     295                 :            : 
     296                 :          0 :         mid->board = (struct mid8250_board *)id->driver_data;
     297                 :          0 :         bar = FL_GET_BASE(mid->board->flags);
     298                 :            : 
     299                 :          0 :         memset(&uart, 0, sizeof(struct uart_8250_port));
     300                 :            : 
     301                 :          0 :         uart.port.dev = &pdev->dev;
     302                 :          0 :         uart.port.irq = pdev->irq;
     303                 :          0 :         uart.port.private_data = mid;
     304                 :          0 :         uart.port.type = PORT_16750;
     305                 :          0 :         uart.port.iotype = UPIO_MEM;
     306                 :          0 :         uart.port.uartclk = mid->board->base_baud * 16;
     307                 :          0 :         uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE;
     308                 :          0 :         uart.port.set_termios = mid8250_set_termios;
     309                 :            : 
     310                 :          0 :         uart.port.mapbase = pci_resource_start(pdev, bar);
     311                 :          0 :         uart.port.membase = pcim_iomap(pdev, bar, 0);
     312         [ #  # ]:          0 :         if (!uart.port.membase)
     313                 :            :                 return -ENOMEM;
     314                 :            : 
     315         [ #  # ]:          0 :         if (mid->board->setup) {
     316                 :          0 :                 ret = mid->board->setup(mid, &uart.port);
     317         [ #  # ]:          0 :                 if (ret)
     318                 :            :                         return ret;
     319                 :            :         }
     320                 :            : 
     321                 :          0 :         ret = mid8250_dma_setup(mid, &uart);
     322         [ #  # ]:          0 :         if (ret)
     323                 :          0 :                 goto err;
     324                 :            : 
     325                 :          0 :         ret = serial8250_register_8250_port(&uart);
     326         [ #  # ]:          0 :         if (ret < 0)
     327                 :          0 :                 goto err;
     328                 :            : 
     329                 :          0 :         mid->line = ret;
     330                 :            : 
     331                 :          0 :         pci_set_drvdata(pdev, mid);
     332                 :          0 :         return 0;
     333                 :          0 : err:
     334         [ #  # ]:          0 :         if (mid->board->exit)
     335                 :          0 :                 mid->board->exit(mid);
     336                 :            :         return ret;
     337                 :            : }
     338                 :            : 
     339                 :          0 : static void mid8250_remove(struct pci_dev *pdev)
     340                 :            : {
     341                 :          0 :         struct mid8250 *mid = pci_get_drvdata(pdev);
     342                 :            : 
     343                 :          0 :         serial8250_unregister_port(mid->line);
     344                 :            : 
     345         [ #  # ]:          0 :         if (mid->board->exit)
     346                 :          0 :                 mid->board->exit(mid);
     347                 :          0 : }
     348                 :            : 
     349                 :            : static const struct mid8250_board pnw_board = {
     350                 :            :         .flags = FL_BASE0,
     351                 :            :         .freq = 50000000,
     352                 :            :         .base_baud = 115200,
     353                 :            :         .setup = pnw_setup,
     354                 :            : };
     355                 :            : 
     356                 :            : static const struct mid8250_board tng_board = {
     357                 :            :         .flags = FL_BASE0,
     358                 :            :         .freq = 38400000,
     359                 :            :         .base_baud = 1843200,
     360                 :            :         .setup = tng_setup,
     361                 :            : };
     362                 :            : 
     363                 :            : static const struct mid8250_board dnv_board = {
     364                 :            :         .flags = FL_BASE1,
     365                 :            :         .freq = 133333333,
     366                 :            :         .base_baud = 115200,
     367                 :            :         .setup = dnv_setup,
     368                 :            :         .exit = dnv_exit,
     369                 :            : };
     370                 :            : 
     371                 :            : #define MID_DEVICE(id, board) { PCI_VDEVICE(INTEL, id), (kernel_ulong_t)&board }
     372                 :            : 
     373                 :            : static const struct pci_device_id pci_ids[] = {
     374                 :            :         MID_DEVICE(PCI_DEVICE_ID_INTEL_PNW_UART1, pnw_board),
     375                 :            :         MID_DEVICE(PCI_DEVICE_ID_INTEL_PNW_UART2, pnw_board),
     376                 :            :         MID_DEVICE(PCI_DEVICE_ID_INTEL_PNW_UART3, pnw_board),
     377                 :            :         MID_DEVICE(PCI_DEVICE_ID_INTEL_TNG_UART, tng_board),
     378                 :            :         MID_DEVICE(PCI_DEVICE_ID_INTEL_CDF_UART, dnv_board),
     379                 :            :         MID_DEVICE(PCI_DEVICE_ID_INTEL_DNV_UART, dnv_board),
     380                 :            :         { },
     381                 :            : };
     382                 :            : MODULE_DEVICE_TABLE(pci, pci_ids);
     383                 :            : 
     384                 :            : static struct pci_driver mid8250_pci_driver = {
     385                 :            :         .name           = "8250_mid",
     386                 :            :         .id_table       = pci_ids,
     387                 :            :         .probe          = mid8250_probe,
     388                 :            :         .remove         = mid8250_remove,
     389                 :            : };
     390                 :            : 
     391                 :          3 : module_pci_driver(mid8250_pci_driver);
     392                 :            : 
     393                 :            : MODULE_AUTHOR("Intel Corporation");
     394                 :            : MODULE_LICENSE("GPL v2");
     395                 :            : MODULE_DESCRIPTION("Intel MID UART driver");

Generated by: LCOV version 1.14