diff options
Diffstat (limited to 'board/scalys/simc-t2081/dragonfruit.c')
-rw-r--r-- | board/scalys/simc-t2081/dragonfruit.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/board/scalys/simc-t2081/dragonfruit.c b/board/scalys/simc-t2081/dragonfruit.c new file mode 100644 index 0000000..286b2c2 --- /dev/null +++ b/board/scalys/simc-t2081/dragonfruit.c @@ -0,0 +1,169 @@ +/* + * Copyright 2017 Scalys B.V. + * opensource@scalys.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/gpio.h> +#include "dragonfruit.h" + +/* + * SERDER MUX Configuration pins: + * IFC_A25 : GPIO2_25 : SERDES_CLK_ MUX_SER0_1_SEL + * IFC_A26 : GPIO2_26 : SERDES_CLK_ MUX_SER2_3_SEL + * IFC_A27 : GPIO2_27 : SERDES_CLK_ MUX_SER5_6_SEL + */ +#define MUX_SER0_1_SEL MPC85XX_GPIO_NR(2, 25) +#define MUX_SER2_3_SEL MPC85XX_GPIO_NR(2, 26) +#define MUX_SER5_6_SEL MPC85XX_GPIO_NR(2, 27) +#define SERDES_CLK_OE MPC85XX_GPIO_NR(2, 29) + +/* + * MUX_SER0_1_SEL + * 0: SERDES A => Slot1, lane 0 + * SERDES B => Slot1, lane 1 + * 1: SERDES A => CS4315 retimer => SFP+ 0 + * SERDES B => CS4315 retimer => SFP+ 1 + */ +#define SER_0_1_SLOT1 0 +#define SER_0_1_SFP01 1 + +/* + * MUX_SER2_3_SEL + * 0: SERDES C => Slot1, lane 2 + * SERDES D => Slot1, lane 3 + * 1: SERDES C => QSFP+ 2 + * SERDES D => QSFP+ 3 + */ +#define SER_2_3_SLOT1 0 +#define SER_2_3_SFP23 2 + +/* + * SERDES E => Slot 4, lane 0 + */ + +/* MUX_SER5_6_SEL + * 0: SERDES F => SLOT4, lane 1 + * SERDES G => SLOT4, lane 2 + * 1: SERDES F => SLOT2 + * SERDES G => SLOT3 + */ +#define SER_5_6_SLOT4 0 +#define SER_5_6_SLOT23 4 + + +/* + * SERDES H => Slot 4, lane 3 + */ + +int scalys_carrier_setup_muxing(int serdes_config) +{ + int ret = 0; + int mux_config = 0; + + ret = gpio_request(MUX_SER0_1_SEL, "mux_ser0_1_sel"); + if (ret != 0) { + printf("gpio request failed(%i)\n", ret); + } + gpio_request(MUX_SER2_3_SEL, "mux_ser2_3_sel"); + gpio_request(MUX_SER5_6_SEL, "mux_ser5_6_sel"); + gpio_request(SERDES_CLK_OE, "serdes_clk_oe"); + + + /* + * SERDES options for each target as supported by the dragonfruit + * carrier board. Refer to the QorIQ reference manual for the SERDES options table + * and all relevant information. + * + * Note: The SERDES lanes A&B, C&D, and F&G can only be switched + * as pairs using the multiplexers. Which means some SERDES options are only partly usable. + * + * Note 2/TODO: SERDES PLL2 must be powered down using SRDS_PLL_PD_S1 when + * SRDS_PRTCL_S1 is any of the following values: 0x00, 0x40, 0x60, 0x67, + * 0x85, 0x87, 0x8D, 0x45. + * + * T2081 has 8 SERDES lanes at up to 10GHz (ie. SERDES 2 configurations are DNC) + * + */ + switch(serdes_config){ +#if defined(CONFIG_PPC_T2081) + /* TODO: test all major cases */ + case 0x6E: + case 0xC8: + case 0xD6: + case 0x6C: + mux_config = SER_5_6_SLOT4 | SER_2_3_SFP23 | SER_0_1_SFP01; + break; + case 0xAA: /* Note 2 */ + mux_config = SER_5_6_SLOT4 | SER_2_3_SLOT1 | SER_0_1_SLOT1; + break; + case 0xBC: /* Note 2 */ + mux_config = SER_5_6_SLOT4 | SER_2_3_SFP23 | SER_0_1_SLOT1; + break; + case 0xCA: + case 0xF2: /* Note 2 */ + case 0xF8: + case 0xFA: + case 0x70: + mux_config = SER_5_6_SLOT23 | SER_2_3_SFP23 | SER_0_1_SFP01; + break; + case 0xDE: /* Note 2 */ + case 0xE0: /* Note 2 */ + mux_config = SER_5_6_SLOT23 | SER_2_3_SLOT1 | SER_0_1_SLOT1; + break; +#else +#error "Invalid or unspecified target cpu for dragonfruit carrier board!" +#endif + default: + printf("Unsupported SERDES configuration (%02x) detected for dragonfruit carrier board (Warning: Using default multiplexer settings)!\n", serdes_config); + } + + + + + + + printf("-----------------------------------------------------\n"); + printf("Serdes lane configuration:\n"); + if ((mux_config & 1) > 0) { + gpio_direction_output(MUX_SER0_1_SEL, 1); + printf("A: SFP slot 0 (T2081 only)\n"); + printf("B: SFP slot 1\n"); + } else { + gpio_direction_output(MUX_SER0_1_SEL, 0); + printf("A: PCIe slot 1 on lane 0\n"); + printf("B: PCIe slot 1 on lane 1\n"); + } + + if ((mux_config & 2) > 0) { + gpio_direction_output(MUX_SER2_3_SEL, 1); + printf("C: SFP slot 2\n"); + printf("D: SFP slot 3\n"); + } else { + gpio_direction_output(MUX_SER2_3_SEL, 0); + printf("C: PCIe slot 1 on lane 2\n"); + printf("D: PCIe slot 1 on lane 3\n"); + } + + printf("E: PCIe slot 4 on lane 0\n"); + + if ((mux_config & 4) > 0) { + gpio_direction_output(MUX_SER5_6_SEL, 1); + printf("F: PCIe slot 2 on lane 0\n"); + printf("G: PCIe slot 3 on lane 0\n"); + } else { + gpio_direction_output(MUX_SER5_6_SEL, 0); + printf("F: PCIe slot 4 on lane 1\n"); + printf("G: PCIe slot 4 on lane 2\n"); + } + + printf("H: PCIe slot 4 on lane 3\n"); + printf("-----------------------------------------------------\n"); + + /* Enable serdes clock */ + gpio_direction_output(SERDES_CLK_OE, 1); + + return ret; +} |