uboot/board/keymile/kmp204x/pci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2013 Keymile AG
   4 * Valentin Longchamp <valentin.longchamp@keymile.com>
   5 *
   6 * Copyright 2007-2011 Freescale Semiconductor, Inc.
   7 */
   8
   9#include <common.h>
  10#include <command.h>
  11#include <init.h>
  12#include <pci.h>
  13#include <asm/fsl_pci.h>
  14#include <linux/libfdt.h>
  15#include <fdt_support.h>
  16#include <asm/fsl_serdes.h>
  17#include <linux/errno.h>
  18
  19#include "../common/qrio.h"
  20#include "kmp204x.h"
  21
  22#define PROM_SEL_L      11
  23/* control the PROM_SEL_L signal*/
  24static void toggle_fpga_eeprom_bus(bool cpu_own)
  25{
  26        qrio_gpio_direction_output(QRIO_GPIO_A, PROM_SEL_L, !cpu_own);
  27}
  28
  29#define CONF_SEL_L      10
  30#define FPGA_PROG_L     19
  31#define FPGA_DONE       18
  32#define FPGA_INIT_L     17
  33
  34int trigger_fpga_config(void)
  35{
  36        int ret = 0, init_l;
  37        /* approx 10ms */
  38        u32 timeout = 10000;
  39
  40        /* make sure the FPGA_can access the EEPROM */
  41        toggle_fpga_eeprom_bus(false);
  42
  43        /* assert CONF_SEL_L to be able to drive FPGA_PROG_L */
  44        qrio_gpio_direction_output(QRIO_GPIO_A, CONF_SEL_L, 0);
  45
  46        /* trigger the config start */
  47        qrio_gpio_direction_output(QRIO_GPIO_A, FPGA_PROG_L, 0);
  48
  49        /* small delay for INIT_L line */
  50        udelay(10);
  51
  52        /* wait for FPGA_INIT to be asserted */
  53        do {
  54                init_l = qrio_get_gpio(QRIO_GPIO_A, FPGA_INIT_L);
  55                if (timeout-- == 0) {
  56                        printf("FPGA_INIT timeout\n");
  57                        ret = -EFAULT;
  58                        break;
  59                }
  60                udelay(10);
  61        } while (init_l);
  62
  63        /* deassert FPGA_PROG, config should start */
  64        qrio_set_gpio(QRIO_GPIO_A, FPGA_PROG_L, 1);
  65
  66        return ret;
  67}
  68
  69/* poll the FPGA_DONE signal and give the EEPROM back to the QorIQ */
  70static int wait_for_fpga_config(void)
  71{
  72        int ret = 0, done;
  73        /* approx 5 s */
  74        u32 timeout = 500000;
  75
  76        printf("PCIe FPGA config:");
  77        do {
  78                done = qrio_get_gpio(QRIO_GPIO_A, FPGA_DONE);
  79                if (timeout-- == 0) {
  80                        printf(" FPGA_DONE timeout\n");
  81                        ret = -EFAULT;
  82                        goto err_out;
  83                }
  84                udelay(10);
  85        } while (!done);
  86
  87        printf(" done\n");
  88
  89err_out:
  90        /* deactive CONF_SEL and give the CPU conf EEPROM access */
  91        qrio_set_gpio(QRIO_GPIO_A, CONF_SEL_L, 1);
  92        toggle_fpga_eeprom_bus(true);
  93
  94        return ret;
  95}
  96
  97#define PCIE_SW_RST     14
  98#define PEXHC_RST       13
  99#define HOOPER_RST      12
 100
 101void pci_init_board(void)
 102{
 103        qrio_prstcfg(PCIE_SW_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
 104        qrio_prstcfg(PEXHC_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
 105        qrio_prstcfg(HOOPER_RST, PRSTCFG_POWUP_UNIT_CORE_RST);
 106
 107        /* wait for the PCIe FPGA to be configured
 108         * it has been triggered earlier in board_early_init_r */
 109        if (wait_for_fpga_config())
 110                printf("error finishing PCIe FPGA config\n");
 111
 112        qrio_prst(PCIE_SW_RST, false, false);
 113        qrio_prst(PEXHC_RST, false, false);
 114        qrio_prst(HOOPER_RST, false, false);
 115        /* Hooper is not direcly PCIe capable */
 116        mdelay(50);
 117
 118        fsl_pcie_init_board(0);
 119}
 120
 121void pci_of_setup(void *blob, bd_t *bd)
 122{
 123        FT_FSL_PCI_SETUP;
 124}
 125