uboot/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) Marvell International Ltd. and its affiliates
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0
   5 */
   6
   7#include <common.h>
   8#include <spl.h>
   9#include <asm/io.h>
  10#include <asm/arch/cpu.h>
  11#include <asm/arch/soc.h>
  12
  13#include "ctrl_pex.h"
  14#include "sys_env_lib.h"
  15
  16__weak void board_pex_config(void)
  17{
  18        /* nothing in this weak default implementation */
  19}
  20
  21int hws_pex_config(const struct serdes_map *serdes_map, u8 count)
  22{
  23        u32 pex_idx, tmp, next_busno, first_busno, temp_pex_reg,
  24            temp_reg, addr, dev_id, ctrl_mode;
  25        enum serdes_type serdes_type;
  26        u32 idx;
  27
  28        DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
  29
  30        for (idx = 0; idx < count; idx++) {
  31                serdes_type = serdes_map[idx].serdes_type;
  32                /* configuration for PEX only */
  33                if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
  34                    (serdes_type != PEX2) && (serdes_type != PEX3))
  35                        continue;
  36
  37                if ((serdes_type != PEX0) &&
  38                    ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
  39                     (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
  40                        /* for PEX by4 - relevant for the first port only */
  41                        continue;
  42                }
  43
  44                pex_idx = serdes_type - PEX0;
  45                tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
  46                tmp &= ~(0xf << 20);
  47                tmp |= (0x4 << 20);
  48                reg_write(PEX_CAPABILITIES_REG(pex_idx), tmp);
  49        }
  50
  51        tmp = reg_read(SOC_CTRL_REG);
  52        tmp &= ~0x03;
  53
  54        for (idx = 0; idx < count; idx++) {
  55                serdes_type = serdes_map[idx].serdes_type;
  56                if ((serdes_type != PEX0) &&
  57                    ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
  58                     (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
  59                        /* for PEX by4 - relevant for the first port only */
  60                        continue;
  61                }
  62
  63                switch (serdes_type) {
  64                case PEX0:
  65                        tmp |= 0x1 << PCIE0_ENABLE_OFFS;
  66                        break;
  67                case PEX1:
  68                        tmp |= 0x1 << PCIE1_ENABLE_OFFS;
  69                        break;
  70                case PEX2:
  71                        tmp |= 0x1 << PCIE2_ENABLE_OFFS;
  72                        break;
  73                case PEX3:
  74                        tmp |= 0x1 << PCIE3_ENABLE_OFFS;
  75                        break;
  76                default:
  77                        break;
  78                }
  79        }
  80
  81        reg_write(SOC_CTRL_REG, tmp);
  82
  83        /* Support gen1/gen2 */
  84        DEBUG_INIT_FULL_S("Support gen1/gen2\n");
  85
  86        board_pex_config();
  87
  88        next_busno = 0;
  89        mdelay(150);
  90
  91        for (idx = 0; idx < count; idx++) {
  92                serdes_type = serdes_map[idx].serdes_type;
  93                DEBUG_INIT_FULL_S(" serdes_type=0x");
  94                DEBUG_INIT_FULL_D(serdes_type, 8);
  95                DEBUG_INIT_FULL_S("\n");
  96                DEBUG_INIT_FULL_S(" idx=0x");
  97                DEBUG_INIT_FULL_D(idx, 8);
  98                DEBUG_INIT_FULL_S("\n");
  99
 100                /* Configuration for PEX only */
 101                if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
 102                    (serdes_type != PEX2) && (serdes_type != PEX3))
 103                        continue;
 104
 105                if ((serdes_type != PEX0) &&
 106                    ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
 107                     (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
 108                        /* for PEX by4 - relevant for the first port only */
 109                        continue;
 110                }
 111
 112                pex_idx = serdes_type - PEX0;
 113                tmp = reg_read(PEX_DBG_STATUS_REG(pex_idx));
 114
 115                first_busno = next_busno;
 116                if ((tmp & 0x7f) != 0x7e) {
 117                        DEBUG_INIT_S("PCIe, Idx ");
 118                        DEBUG_INIT_D(pex_idx, 1);
 119                        DEBUG_INIT_S(": detected no link\n");
 120                        continue;
 121                }
 122
 123                next_busno++;
 124                temp_pex_reg = reg_read((PEX_CFG_DIRECT_ACCESS
 125                                         (pex_idx, PEX_LINK_CAPABILITY_REG)));
 126                temp_pex_reg &= 0xf;
 127                if (temp_pex_reg != 0x2)
 128                        continue;
 129
 130                temp_reg = (reg_read(PEX_CFG_DIRECT_ACCESS(
 131                                             pex_idx,
 132                                             PEX_LINK_CTRL_STAT_REG)) &
 133                            0xf0000) >> 16;
 134
 135                /* Check if the link established is GEN1 */
 136                DEBUG_INIT_FULL_S
 137                        ("Checking if the link established is gen1\n");
 138                if (temp_reg != 0x1)
 139                        continue;
 140
 141                pex_local_bus_num_set(pex_idx, first_busno);
 142                pex_local_dev_num_set(pex_idx, 1);
 143                DEBUG_INIT_FULL_S("PCIe, Idx ");
 144                DEBUG_INIT_FULL_D(pex_idx, 1);
 145
 146                DEBUG_INIT_S(":** Link is Gen1, check the EP capability\n");
 147                /* link is Gen1, check the EP capability */
 148                addr = pex_config_read(pex_idx, first_busno, 0, 0, 0x34) & 0xff;
 149                DEBUG_INIT_FULL_C("pex_config_read: return addr=0x%x", addr, 4);
 150                if (addr == 0xff) {
 151                        DEBUG_INIT_FULL_C
 152                                ("pex_config_read: return 0xff -->PCIe (%d): Detected No Link.",
 153                                 pex_idx, 1);
 154                        continue;
 155                }
 156
 157                while ((pex_config_read(pex_idx, first_busno, 0, 0, addr)
 158                        & 0xff) != 0x10) {
 159                        addr = (pex_config_read(pex_idx, first_busno, 0,
 160                                                0, addr) & 0xff00) >> 8;
 161                }
 162
 163                /* Check for Gen2 and above */
 164                if ((pex_config_read(pex_idx, first_busno, 0, 0,
 165                                     addr + 0xc) & 0xf) < 0x2) {
 166                        DEBUG_INIT_S("PCIe, Idx ");
 167                        DEBUG_INIT_D(pex_idx, 1);
 168                        DEBUG_INIT_S(": remains Gen1\n");
 169                        continue;
 170                }
 171
 172                tmp = reg_read(PEX_LINK_CTRL_STATUS2_REG(pex_idx));
 173                DEBUG_RD_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
 174                tmp &= ~(BIT(0) | BIT(1));
 175                tmp |= BIT(1);
 176                tmp |= BIT(6);  /* Select Deemphasize (-3.5d_b) */
 177                reg_write(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
 178                DEBUG_WR_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
 179
 180                tmp = reg_read(PEX_CTRL_REG(pex_idx));
 181                DEBUG_RD_REG(PEX_CTRL_REG(pex_idx), tmp);
 182                tmp |= BIT(10);
 183                reg_write(PEX_CTRL_REG(pex_idx), tmp);
 184                DEBUG_WR_REG(PEX_CTRL_REG(pex_idx), tmp);
 185
 186                /*
 187                 * We need to wait 10ms before reading the PEX_DBG_STATUS_REG
 188                 * in order not to read the status of the former state
 189                 */
 190                mdelay(10);
 191
 192                DEBUG_INIT_S("PCIe, Idx ");
 193                DEBUG_INIT_D(pex_idx, 1);
 194                DEBUG_INIT_S
 195                        (": Link upgraded to Gen2 based on client capabilities\n");
 196        }
 197
 198        /* Update pex DEVICE ID */
 199        ctrl_mode = sys_env_model_get();
 200
 201        for (idx = 0; idx < count; idx++) {
 202                serdes_type = serdes_map[idx].serdes_type;
 203                /* configuration for PEX only */
 204                if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
 205                    (serdes_type != PEX2) && (serdes_type != PEX3))
 206                        continue;
 207
 208                if ((serdes_type != PEX0) &&
 209                    ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
 210                     (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
 211                        /* for PEX by4 - relevant for the first port only */
 212                        continue;
 213                }
 214
 215                pex_idx = serdes_type - PEX0;
 216                dev_id = reg_read(PEX_CFG_DIRECT_ACCESS
 217                                  (pex_idx, PEX_DEVICE_AND_VENDOR_ID));
 218                dev_id &= 0xffff;
 219                dev_id |= ((ctrl_mode << 16) & 0xffff0000);
 220                reg_write(PEX_CFG_DIRECT_ACCESS
 221                          (pex_idx, PEX_DEVICE_AND_VENDOR_ID), dev_id);
 222        }
 223        DEBUG_INIT_FULL_C("Update PEX Device ID ", ctrl_mode, 4);
 224
 225        return MV_OK;
 226}
 227
 228int pex_local_bus_num_set(u32 pex_if, u32 bus_num)
 229{
 230        u32 pex_status;
 231
 232        DEBUG_INIT_FULL_S("\n### pex_local_bus_num_set ###\n");
 233
 234        if (bus_num >= MAX_PEX_BUSSES) {
 235                DEBUG_INIT_C("pex_local_bus_num_set: Illegal bus number %d\n",
 236                             bus_num, 4);
 237                return MV_BAD_PARAM;
 238        }
 239
 240        pex_status = reg_read(PEX_STATUS_REG(pex_if));
 241        pex_status &= ~PXSR_PEX_BUS_NUM_MASK;
 242        pex_status |=
 243            (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
 244        reg_write(PEX_STATUS_REG(pex_if), pex_status);
 245
 246        return MV_OK;
 247}
 248
 249int pex_local_dev_num_set(u32 pex_if, u32 dev_num)
 250{
 251        u32 pex_status;
 252
 253        DEBUG_INIT_FULL_S("\n### pex_local_dev_num_set ###\n");
 254
 255        pex_status = reg_read(PEX_STATUS_REG(pex_if));
 256        pex_status &= ~PXSR_PEX_DEV_NUM_MASK;
 257        pex_status |=
 258            (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
 259        reg_write(PEX_STATUS_REG(pex_if), pex_status);
 260
 261        return MV_OK;
 262}
 263
 264/*
 265 * pex_config_read - Read from configuration space
 266 *
 267 * DESCRIPTION:
 268 *       This function performs a 32 bit read from PEX configuration space.
 269 *       It supports both type 0 and type 1 of Configuration Transactions
 270 *       (local and over bridge). In order to read from local bus segment, use
 271 *       bus number retrieved from pex_local_bus_num_get(). Other bus numbers
 272 *       will result configuration transaction of type 1 (over bridge).
 273 *
 274 * INPUT:
 275 *       pex_if   - PEX interface number.
 276 *       bus      - PEX segment bus number.
 277 *       dev      - PEX device number.
 278 *       func     - Function number.
 279 *       reg_offs - Register offset.
 280 *
 281 * OUTPUT:
 282 *       None.
 283 *
 284 * RETURN:
 285 *       32bit register data, 0xffffffff on error
 286 */
 287u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off)
 288{
 289        u32 pex_data = 0;
 290        u32 local_dev, local_bus;
 291        u32 pex_status;
 292
 293        pex_status = reg_read(PEX_STATUS_REG(pex_if));
 294        local_dev =
 295            ((pex_status & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS);
 296        local_bus =
 297            ((pex_status & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS);
 298
 299        /*
 300         * In PCI Express we have only one device number
 301         * and this number is the first number we encounter
 302         * else that the local_dev
 303         * spec pex define return on config read/write on any device
 304         */
 305        if (bus == local_bus) {
 306                if (local_dev == 0) {
 307                        /*
 308                         * if local dev is 0 then the first number we encounter
 309                         * after 0 is 1
 310                         */
 311                        if ((dev != 1) && (dev != local_dev))
 312                                return MV_ERROR;
 313                } else {
 314                        /*
 315                         * if local dev is not 0 then the first number we
 316                         * encounter is 0
 317                         */
 318                        if ((dev != 0) && (dev != local_dev))
 319                                return MV_ERROR;
 320                }
 321        }
 322
 323        /* Creating PEX address to be passed */
 324        pex_data = (bus << PXCAR_BUS_NUM_OFFS);
 325        pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS);
 326        pex_data |= (func << PXCAR_FUNC_NUM_OFFS);
 327        /* Legacy register space */
 328        pex_data |= (reg_off & PXCAR_REG_NUM_MASK);
 329        /* Extended register space */
 330        pex_data |= (((reg_off & PXCAR_REAL_EXT_REG_NUM_MASK) >>
 331                      PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
 332        pex_data |= PXCAR_CONFIG_EN;
 333
 334        /* Write the address to the PEX configuration address register */
 335        reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data);
 336
 337        /*
 338         * In order to let the PEX controller absorbed the address
 339         * of the read transaction we perform a validity check that
 340         * the address was written
 341         */
 342        if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if)))
 343                return MV_ERROR;
 344
 345        /* Cleaning Master Abort */
 346        reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND),
 347                    PXSAC_MABORT);
 348        /* Read the Data returned in the PEX Data register */
 349        pex_data = reg_read(PEX_CFG_DATA_REG(pex_if));
 350
 351        DEBUG_INIT_FULL_C(" --> ", pex_data, 4);
 352
 353        return pex_data;
 354}
 355