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