uboot/drivers/pci/pci-rcar-gen2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Renesas RCar Gen2 PCIEC driver
   4 *
   5 * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
   6 */
   7
   8#include <common.h>
   9#include <asm/io.h>
  10#include <clk.h>
  11#include <dm.h>
  12#include <errno.h>
  13#include <pci.h>
  14#include <linux/bitops.h>
  15
  16/* AHB-PCI Bridge PCI communication registers */
  17#define RCAR_AHBPCI_PCICOM_OFFSET       0x800
  18
  19#define RCAR_PCIAHB_WIN1_CTR_REG        (RCAR_AHBPCI_PCICOM_OFFSET + 0x00)
  20#define RCAR_PCIAHB_WIN2_CTR_REG        (RCAR_AHBPCI_PCICOM_OFFSET + 0x04)
  21#define RCAR_PCIAHB_PREFETCH0           0x0
  22#define RCAR_PCIAHB_PREFETCH4           0x1
  23#define RCAR_PCIAHB_PREFETCH8           0x2
  24#define RCAR_PCIAHB_PREFETCH16          0x3
  25
  26#define RCAR_AHBPCI_WIN1_CTR_REG        (RCAR_AHBPCI_PCICOM_OFFSET + 0x10)
  27#define RCAR_AHBPCI_WIN2_CTR_REG        (RCAR_AHBPCI_PCICOM_OFFSET + 0x14)
  28#define RCAR_AHBPCI_WIN_CTR_MEM         (3 << 1)
  29#define RCAR_AHBPCI_WIN_CTR_CFG         (5 << 1)
  30#define RCAR_AHBPCI_WIN1_HOST           BIT(30)
  31#define RCAR_AHBPCI_WIN1_DEVICE         BIT(31)
  32
  33#define RCAR_PCI_INT_ENABLE_REG         (RCAR_AHBPCI_PCICOM_OFFSET + 0x20)
  34#define RCAR_PCI_INT_STATUS_REG         (RCAR_AHBPCI_PCICOM_OFFSET + 0x24)
  35#define RCAR_PCI_INT_SIGTABORT          BIT(0)
  36#define RCAR_PCI_INT_SIGRETABORT        BIT(1)
  37#define RCAR_PCI_INT_REMABORT           BIT(2)
  38#define RCAR_PCI_INT_PERR               BIT(3)
  39#define RCAR_PCI_INT_SIGSERR            BIT(4)
  40#define RCAR_PCI_INT_RESERR             BIT(5)
  41#define RCAR_PCI_INT_WIN1ERR            BIT(12)
  42#define RCAR_PCI_INT_WIN2ERR            BIT(13)
  43#define RCAR_PCI_INT_A                  BIT(16)
  44#define RCAR_PCI_INT_B                  BIT(17)
  45#define RCAR_PCI_INT_PME                BIT(19)
  46#define RCAR_PCI_INT_ALLERRORS (RCAR_PCI_INT_SIGTABORT          | \
  47                                RCAR_PCI_INT_SIGRETABORT        | \
  48                                RCAR_PCI_INT_SIGRETABORT        | \
  49                                RCAR_PCI_INT_REMABORT           | \
  50                                RCAR_PCI_INT_PERR               | \
  51                                RCAR_PCI_INT_SIGSERR            | \
  52                                RCAR_PCI_INT_RESERR             | \
  53                                RCAR_PCI_INT_WIN1ERR            | \
  54                                RCAR_PCI_INT_WIN2ERR)
  55
  56#define RCAR_AHB_BUS_CTR_REG            (RCAR_AHBPCI_PCICOM_OFFSET + 0x30)
  57#define RCAR_AHB_BUS_MMODE_HTRANS       BIT(0)
  58#define RCAR_AHB_BUS_MMODE_BYTE_BURST   BIT(1)
  59#define RCAR_AHB_BUS_MMODE_WR_INCR      BIT(2)
  60#define RCAR_AHB_BUS_MMODE_HBUS_REQ     BIT(7)
  61#define RCAR_AHB_BUS_SMODE_READYCTR     BIT(17)
  62#define RCAR_AHB_BUS_MODE               (RCAR_AHB_BUS_MMODE_HTRANS |    \
  63                                        RCAR_AHB_BUS_MMODE_BYTE_BURST | \
  64                                        RCAR_AHB_BUS_MMODE_WR_INCR |    \
  65                                        RCAR_AHB_BUS_MMODE_HBUS_REQ |   \
  66                                        RCAR_AHB_BUS_SMODE_READYCTR)
  67
  68#define RCAR_USBCTR_REG                 (RCAR_AHBPCI_PCICOM_OFFSET + 0x34)
  69#define RCAR_USBCTR_USBH_RST            BIT(0)
  70#define RCAR_USBCTR_PCICLK_MASK         BIT(1)
  71#define RCAR_USBCTR_PLL_RST             BIT(2)
  72#define RCAR_USBCTR_DIRPD               BIT(8)
  73#define RCAR_USBCTR_PCIAHB_WIN2_EN      BIT(9)
  74#define RCAR_USBCTR_PCIAHB_WIN1_256M    (0 << 10)
  75#define RCAR_USBCTR_PCIAHB_WIN1_512M    (1 << 10)
  76#define RCAR_USBCTR_PCIAHB_WIN1_1G      (2 << 10)
  77#define RCAR_USBCTR_PCIAHB_WIN1_2G      (3 << 10)
  78#define RCAR_USBCTR_PCIAHB_WIN1_MASK    (3 << 10)
  79
  80#define RCAR_PCI_ARBITER_CTR_REG        (RCAR_AHBPCI_PCICOM_OFFSET + 0x40)
  81#define RCAR_PCI_ARBITER_PCIREQ0        BIT(0)
  82#define RCAR_PCI_ARBITER_PCIREQ1        BIT(1)
  83#define RCAR_PCI_ARBITER_PCIBP_MODE     BIT(12)
  84
  85#define RCAR_PCI_UNIT_REV_REG           (RCAR_AHBPCI_PCICOM_OFFSET + 0x48)
  86
  87struct rcar_gen2_pci_priv {
  88        fdt_addr_t              cfg_base;
  89        fdt_addr_t              mem_base;
  90};
  91
  92static int rcar_gen2_pci_addr_valid(pci_dev_t d, uint offset)
  93{
  94        u32 slot;
  95
  96        if (PCI_FUNC(d))
  97                return -EINVAL;
  98
  99        /* Only one EHCI/OHCI device built-in */
 100        slot = PCI_DEV(d);
 101        if (slot != 1 && slot != 2)
 102                return -EINVAL;
 103
 104        /* bridge logic only has registers to 0x40 */
 105        if (slot == 0x0 && offset >= 0x40)
 106                return -EINVAL;
 107
 108        return 0;
 109}
 110
 111static u32 get_bus_address(const struct udevice *dev, pci_dev_t bdf, u32 offset)
 112{
 113        struct rcar_gen2_pci_priv *priv = dev_get_priv(dev);
 114
 115        return priv->cfg_base + (PCI_DEV(bdf) >> 1) * 0x100 + (offset & ~3);
 116}
 117
 118static u32 setup_bus_address(struct udevice *dev, pci_dev_t bdf, u32 offset)
 119{
 120        struct rcar_gen2_pci_priv *priv = dev_get_priv(dev);
 121        u32 reg;
 122
 123        reg = PCI_DEV(bdf) ? RCAR_AHBPCI_WIN1_DEVICE : RCAR_AHBPCI_WIN1_HOST;
 124        reg |= RCAR_AHBPCI_WIN_CTR_CFG;
 125        writel(reg, priv->cfg_base + RCAR_AHBPCI_WIN1_CTR_REG);
 126
 127        return get_bus_address(dev, bdf, offset);
 128}
 129
 130static int rcar_gen2_pci_read_config(const struct udevice *dev, pci_dev_t bdf,
 131                                     uint offset, ulong *value,
 132                                     enum pci_size_t size)
 133{
 134        u32 addr, reg;
 135        int ret;
 136
 137        ret = rcar_gen2_pci_addr_valid(bdf, offset);
 138        if (ret) {
 139                *value = pci_get_ff(size);
 140                return 0;
 141        }
 142
 143        addr = get_bus_address(dev, bdf, offset);
 144        reg = readl(addr);
 145        *value = pci_conv_32_to_size(reg, offset, size);
 146
 147        return 0;
 148}
 149
 150static int rcar_gen2_pci_write_config(struct udevice *dev, pci_dev_t bdf,
 151                                      uint offset, ulong value,
 152                                      enum pci_size_t size)
 153{
 154        u32 addr, reg, old;
 155        int ret;
 156
 157        ret = rcar_gen2_pci_addr_valid(bdf, offset);
 158        if (ret)
 159                return ret;
 160
 161        addr = get_bus_address(dev, bdf, offset);
 162
 163        old = readl(addr);
 164        reg = pci_conv_size_to_32(old, value, offset, size);
 165        writel(reg, addr);
 166
 167        return 0;
 168}
 169
 170static int rcar_gen2_pci_probe(struct udevice *dev)
 171{
 172        struct rcar_gen2_pci_priv *priv = dev_get_priv(dev);
 173        struct clk pci_clk;
 174        u32 devad;
 175        int ret;
 176
 177        ret = clk_get_by_index(dev, 0, &pci_clk);
 178        if (ret)
 179                return ret;
 180
 181        ret = clk_enable(&pci_clk);
 182        if (ret)
 183                return ret;
 184
 185        /* Clock & Reset & Direct Power Down */
 186        clrsetbits_le32(priv->cfg_base + RCAR_USBCTR_REG,
 187                        RCAR_USBCTR_DIRPD | RCAR_USBCTR_PCICLK_MASK |
 188                        RCAR_USBCTR_USBH_RST,
 189                        RCAR_USBCTR_PCIAHB_WIN1_1G);
 190        clrbits_le32(priv->cfg_base + RCAR_USBCTR_REG, RCAR_USBCTR_PLL_RST);
 191
 192        /* AHB-PCI Bridge Communication Registers */
 193        writel(RCAR_AHB_BUS_MODE, priv->cfg_base + RCAR_AHB_BUS_CTR_REG);
 194        writel((CONFIG_SYS_SDRAM_BASE & 0xf0000000) | RCAR_PCIAHB_PREFETCH16,
 195               priv->cfg_base + RCAR_PCIAHB_WIN1_CTR_REG);
 196        writel(0xf0000000 | RCAR_PCIAHB_PREFETCH16,
 197               priv->cfg_base + RCAR_PCIAHB_WIN2_CTR_REG);
 198        writel(priv->mem_base | RCAR_AHBPCI_WIN_CTR_MEM,
 199               priv->cfg_base + RCAR_AHBPCI_WIN2_CTR_REG);
 200        setbits_le32(priv->cfg_base + RCAR_PCI_ARBITER_CTR_REG,
 201                     RCAR_PCI_ARBITER_PCIREQ0 | RCAR_PCI_ARBITER_PCIREQ1 |
 202                     RCAR_PCI_ARBITER_PCIBP_MODE);
 203
 204        /* PCI Configuration Registers for AHBPCI */
 205        devad = setup_bus_address(dev, PCI_BDF(0, 0, 0), 0);
 206        writel(priv->cfg_base + 0x800, devad + PCI_BASE_ADDRESS_0);
 207        writel(CONFIG_SYS_SDRAM_BASE & 0xf0000000, devad + PCI_BASE_ADDRESS_1);
 208        writel(0xf0000000, devad + PCI_BASE_ADDRESS_2);
 209        writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
 210               PCI_COMMAND_PARITY | PCI_COMMAND_SERR,
 211               devad + PCI_COMMAND);
 212
 213        /* PCI Configuration Registers for OHCI */
 214        devad = setup_bus_address(dev, PCI_BDF(0, 1, 0), 0);
 215        writel(priv->mem_base + 0x0, devad + PCI_BASE_ADDRESS_0);
 216        writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
 217               PCI_COMMAND_PARITY | PCI_COMMAND_SERR,
 218               devad + PCI_COMMAND);
 219
 220        /* PCI Configuration Registers for EHCI */
 221        devad = setup_bus_address(dev, PCI_BDF(0, 2, 0), 0);
 222        writel(priv->mem_base + 0x1000, devad + PCI_BASE_ADDRESS_0);
 223        writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
 224               PCI_COMMAND_PARITY | PCI_COMMAND_SERR,
 225               devad + PCI_COMMAND);
 226
 227        /* Enable PCI interrupt */
 228        setbits_le32(priv->cfg_base + RCAR_PCI_INT_ENABLE_REG,
 229                     RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME);
 230
 231        return 0;
 232}
 233
 234static int rcar_gen2_pci_ofdata_to_platdata(struct udevice *dev)
 235{
 236        struct rcar_gen2_pci_priv *priv = dev_get_priv(dev);
 237
 238        priv->cfg_base = devfdt_get_addr_index(dev, 0);
 239        priv->mem_base = devfdt_get_addr_index(dev, 1);
 240        if (!priv->cfg_base || !priv->mem_base)
 241                return -EINVAL;
 242
 243        return 0;
 244}
 245
 246static const struct dm_pci_ops rcar_gen2_pci_ops = {
 247        .read_config    = rcar_gen2_pci_read_config,
 248        .write_config   = rcar_gen2_pci_write_config,
 249};
 250
 251static const struct udevice_id rcar_gen2_pci_ids[] = {
 252        { .compatible = "renesas,pci-rcar-gen2" },
 253        { }
 254};
 255
 256U_BOOT_DRIVER(rcar_gen2_pci) = {
 257        .name                   = "rcar_gen2_pci",
 258        .id                     = UCLASS_PCI,
 259        .of_match               = rcar_gen2_pci_ids,
 260        .ops                    = &rcar_gen2_pci_ops,
 261        .probe                  = rcar_gen2_pci_probe,
 262        .ofdata_to_platdata     = rcar_gen2_pci_ofdata_to_platdata,
 263        .priv_auto_alloc_size   = sizeof(struct rcar_gen2_pci_priv),
 264};
 265