uboot/drivers/pci/pcie_layerscape.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2017-2020 NXP
   4 * Copyright 2014-2015 Freescale Semiconductor, Inc.
   5 * Layerscape PCIe driver
   6 */
   7
   8#include <common.h>
   9#include <log.h>
  10#include <asm/global_data.h>
  11#include <asm/io.h>
  12#include <errno.h>
  13#include <malloc.h>
  14#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
  15        defined(CONFIG_ARM)
  16#include <asm/arch/clock.h>
  17#endif
  18#include "pcie_layerscape.h"
  19
  20DECLARE_GLOBAL_DATA_PTR;
  21
  22LIST_HEAD(ls_pcie_list);
  23
  24unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset)
  25{
  26        return in_le32(pcie->dbi + offset);
  27}
  28
  29void dbi_writel(struct ls_pcie *pcie, unsigned int value, unsigned int offset)
  30{
  31        out_le32(pcie->dbi + offset, value);
  32}
  33
  34unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
  35{
  36        if (pcie->big_endian)
  37                return in_be32(pcie->ctrl + offset);
  38        else
  39                return in_le32(pcie->ctrl + offset);
  40}
  41
  42void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
  43                 unsigned int offset)
  44{
  45        if (pcie->big_endian)
  46                out_be32(pcie->ctrl + offset, value);
  47        else
  48                out_le32(pcie->ctrl + offset, value);
  49}
  50
  51void ls_pcie_dbi_ro_wr_en(struct ls_pcie *pcie)
  52{
  53        u32 reg, val;
  54
  55        reg = PCIE_MISC_CONTROL_1_OFF;
  56        val = dbi_readl(pcie, reg);
  57        val |= PCIE_DBI_RO_WR_EN;
  58        dbi_writel(pcie, val, reg);
  59}
  60
  61void ls_pcie_dbi_ro_wr_dis(struct ls_pcie *pcie)
  62{
  63        u32 reg, val;
  64
  65        reg = PCIE_MISC_CONTROL_1_OFF;
  66        val = dbi_readl(pcie, reg);
  67        val &= ~PCIE_DBI_RO_WR_EN;
  68        dbi_writel(pcie, val, reg);
  69}
  70
  71static int ls_pcie_ltssm(struct ls_pcie *pcie)
  72{
  73        u32 state;
  74        uint svr;
  75
  76        svr = get_svr();
  77        if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) {
  78                state = ctrl_readl(pcie, LS1021_PEXMSCPORTSR(pcie->idx));
  79                state = (state >> LS1021_LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
  80        } else {
  81                state = ctrl_readl(pcie, PCIE_PF_DBG) & LTSSM_STATE_MASK;
  82        }
  83
  84        return state;
  85}
  86
  87int ls_pcie_link_up(struct ls_pcie *pcie)
  88{
  89        int ltssm;
  90
  91        ltssm = ls_pcie_ltssm(pcie);
  92        if (ltssm < LTSSM_PCIE_L0)
  93                return 0;
  94
  95        return 1;
  96}
  97
  98void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
  99                              u64 phys, u64 bus_addr, u64 size)
 100{
 101        dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | idx, PCIE_ATU_VIEWPORT);
 102        dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_BASE);
 103        dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_BASE);
 104        dbi_writel(pcie, (u32)phys + size - 1, PCIE_ATU_LIMIT);
 105        dbi_writel(pcie, (u32)bus_addr, PCIE_ATU_LOWER_TARGET);
 106        dbi_writel(pcie, bus_addr >> 32, PCIE_ATU_UPPER_TARGET);
 107        dbi_writel(pcie, type, PCIE_ATU_CR1);
 108        dbi_writel(pcie, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
 109}
 110
 111/* Use bar match mode and MEM type as default */
 112void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, u32 pf, u32 vf_flag,
 113                             int type, int idx, int bar, u64 phys)
 114{
 115        dbi_writel(pcie, PCIE_ATU_REGION_INBOUND | idx, PCIE_ATU_VIEWPORT);
 116        dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_TARGET);
 117        dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_TARGET);
 118        dbi_writel(pcie, type | PCIE_ATU_FUNC_NUM(pf), PCIE_ATU_CR1);
 119        dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
 120                   (vf_flag ? PCIE_ATU_FUNC_NUM_MATCH_EN : 0) |
 121                   (vf_flag ? PCIE_ATU_VFBAR_MATCH_MODE_EN : 0) |
 122                   PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2);
 123}
 124
 125void ls_pcie_dump_atu(struct ls_pcie *pcie, u32 win_num, u32 type)
 126{
 127        int win_idx;
 128
 129        for (win_idx = 0; win_idx < win_num; win_idx++) {
 130                dbi_writel(pcie, type | win_idx, PCIE_ATU_VIEWPORT);
 131                debug("iATU%d:\n", win_idx);
 132                debug("\tLOWER PHYS 0x%08x\n",
 133                      dbi_readl(pcie, PCIE_ATU_LOWER_BASE));
 134                debug("\tUPPER PHYS 0x%08x\n",
 135                      dbi_readl(pcie, PCIE_ATU_UPPER_BASE));
 136                if (type == PCIE_ATU_REGION_OUTBOUND) {
 137                        debug("\tLOWER BUS  0x%08x\n",
 138                              dbi_readl(pcie, PCIE_ATU_LOWER_TARGET));
 139                        debug("\tUPPER BUS  0x%08x\n",
 140                              dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
 141                        debug("\tLIMIT      0x%08x\n",
 142                              dbi_readl(pcie, PCIE_ATU_LIMIT));
 143                }
 144                debug("\tCR1        0x%08x\n",
 145                      dbi_readl(pcie, PCIE_ATU_CR1));
 146                debug("\tCR2        0x%08x\n",
 147                      dbi_readl(pcie, PCIE_ATU_CR2));
 148        }
 149}
 150