1*d78d3a22SFrançois Tigeot /* 2*d78d3a22SFrançois Tigeot * Copyright 2015 Advanced Micro Devices, Inc. 3*d78d3a22SFrançois Tigeot * 4*d78d3a22SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 5*d78d3a22SFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 6*d78d3a22SFrançois Tigeot * to deal in the Software without restriction, including without limitation 7*d78d3a22SFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*d78d3a22SFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 9*d78d3a22SFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 10*d78d3a22SFrançois Tigeot * 11*d78d3a22SFrançois Tigeot * The above copyright notice and this permission notice shall be included in 12*d78d3a22SFrançois Tigeot * all copies or substantial portions of the Software. 13*d78d3a22SFrançois Tigeot * 14*d78d3a22SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15*d78d3a22SFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16*d78d3a22SFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17*d78d3a22SFrançois Tigeot * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18*d78d3a22SFrançois Tigeot * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19*d78d3a22SFrançois Tigeot * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20*d78d3a22SFrançois Tigeot * OTHER DEALINGS IN THE SOFTWARE. 21*d78d3a22SFrançois Tigeot */ 22*d78d3a22SFrançois Tigeot 23*d78d3a22SFrançois Tigeot #ifndef __AMD_PCIE_HELPERS_H__ 24*d78d3a22SFrançois Tigeot #define __AMD_PCIE_HELPERS_H__ 25*d78d3a22SFrançois Tigeot 26*d78d3a22SFrançois Tigeot #include "amd_pcie.h" 27*d78d3a22SFrançois Tigeot 28*d78d3a22SFrançois Tigeot static inline bool is_pcie_gen3_supported(uint32_t pcie_link_speed_cap) 29*d78d3a22SFrançois Tigeot { 30*d78d3a22SFrançois Tigeot if (pcie_link_speed_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) 31*d78d3a22SFrançois Tigeot return true; 32*d78d3a22SFrançois Tigeot 33*d78d3a22SFrançois Tigeot return false; 34*d78d3a22SFrançois Tigeot } 35*d78d3a22SFrançois Tigeot 36*d78d3a22SFrançois Tigeot static inline bool is_pcie_gen2_supported(uint32_t pcie_link_speed_cap) 37*d78d3a22SFrançois Tigeot { 38*d78d3a22SFrançois Tigeot if (pcie_link_speed_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) 39*d78d3a22SFrançois Tigeot return true; 40*d78d3a22SFrançois Tigeot 41*d78d3a22SFrançois Tigeot return false; 42*d78d3a22SFrançois Tigeot } 43*d78d3a22SFrançois Tigeot 44*d78d3a22SFrançois Tigeot /* Get the new PCIE speed given the ASIC PCIE Cap and the NewState's requested PCIE speed*/ 45*d78d3a22SFrançois Tigeot static inline uint16_t get_pcie_gen_support(uint32_t pcie_link_speed_cap, 46*d78d3a22SFrançois Tigeot uint16_t ns_pcie_gen) 47*d78d3a22SFrançois Tigeot { 48*d78d3a22SFrançois Tigeot uint32_t asic_pcie_link_speed_cap = (pcie_link_speed_cap & 49*d78d3a22SFrançois Tigeot CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_MASK); 50*d78d3a22SFrançois Tigeot uint32_t sys_pcie_link_speed_cap = (pcie_link_speed_cap & 51*d78d3a22SFrançois Tigeot CAIL_PCIE_LINK_SPEED_SUPPORT_MASK); 52*d78d3a22SFrançois Tigeot 53*d78d3a22SFrançois Tigeot switch (asic_pcie_link_speed_cap) { 54*d78d3a22SFrançois Tigeot case CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1: 55*d78d3a22SFrançois Tigeot return PP_PCIEGen1; 56*d78d3a22SFrançois Tigeot 57*d78d3a22SFrançois Tigeot case CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2: 58*d78d3a22SFrançois Tigeot return PP_PCIEGen2; 59*d78d3a22SFrançois Tigeot 60*d78d3a22SFrançois Tigeot case CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3: 61*d78d3a22SFrançois Tigeot return PP_PCIEGen3; 62*d78d3a22SFrançois Tigeot 63*d78d3a22SFrançois Tigeot default: 64*d78d3a22SFrançois Tigeot if (is_pcie_gen3_supported(sys_pcie_link_speed_cap) && 65*d78d3a22SFrançois Tigeot (ns_pcie_gen == PP_PCIEGen3)) { 66*d78d3a22SFrançois Tigeot return PP_PCIEGen3; 67*d78d3a22SFrançois Tigeot } else if (is_pcie_gen2_supported(sys_pcie_link_speed_cap) && 68*d78d3a22SFrançois Tigeot ((ns_pcie_gen == PP_PCIEGen3) || (ns_pcie_gen == PP_PCIEGen2))) { 69*d78d3a22SFrançois Tigeot return PP_PCIEGen2; 70*d78d3a22SFrançois Tigeot } 71*d78d3a22SFrançois Tigeot } 72*d78d3a22SFrançois Tigeot 73*d78d3a22SFrançois Tigeot return PP_PCIEGen1; 74*d78d3a22SFrançois Tigeot } 75*d78d3a22SFrançois Tigeot 76*d78d3a22SFrançois Tigeot static inline uint16_t get_pcie_lane_support(uint32_t pcie_lane_width_cap, 77*d78d3a22SFrançois Tigeot uint16_t ns_pcie_lanes) 78*d78d3a22SFrançois Tigeot { 79*d78d3a22SFrançois Tigeot int i, j; 80*d78d3a22SFrançois Tigeot uint16_t new_pcie_lanes = ns_pcie_lanes; 81*d78d3a22SFrançois Tigeot uint16_t pcie_lanes[7] = {1, 2, 4, 8, 12, 16, 32}; 82*d78d3a22SFrançois Tigeot 83*d78d3a22SFrançois Tigeot switch (pcie_lane_width_cap) { 84*d78d3a22SFrançois Tigeot case 0: 85*d78d3a22SFrançois Tigeot printk(KERN_ERR "No valid PCIE lane width reported"); 86*d78d3a22SFrançois Tigeot break; 87*d78d3a22SFrançois Tigeot case CAIL_PCIE_LINK_WIDTH_SUPPORT_X1: 88*d78d3a22SFrançois Tigeot new_pcie_lanes = 1; 89*d78d3a22SFrançois Tigeot break; 90*d78d3a22SFrançois Tigeot case CAIL_PCIE_LINK_WIDTH_SUPPORT_X2: 91*d78d3a22SFrançois Tigeot new_pcie_lanes = 2; 92*d78d3a22SFrançois Tigeot break; 93*d78d3a22SFrançois Tigeot case CAIL_PCIE_LINK_WIDTH_SUPPORT_X4: 94*d78d3a22SFrançois Tigeot new_pcie_lanes = 4; 95*d78d3a22SFrançois Tigeot break; 96*d78d3a22SFrançois Tigeot case CAIL_PCIE_LINK_WIDTH_SUPPORT_X8: 97*d78d3a22SFrançois Tigeot new_pcie_lanes = 8; 98*d78d3a22SFrançois Tigeot break; 99*d78d3a22SFrançois Tigeot case CAIL_PCIE_LINK_WIDTH_SUPPORT_X12: 100*d78d3a22SFrançois Tigeot new_pcie_lanes = 12; 101*d78d3a22SFrançois Tigeot break; 102*d78d3a22SFrançois Tigeot case CAIL_PCIE_LINK_WIDTH_SUPPORT_X16: 103*d78d3a22SFrançois Tigeot new_pcie_lanes = 16; 104*d78d3a22SFrançois Tigeot break; 105*d78d3a22SFrançois Tigeot case CAIL_PCIE_LINK_WIDTH_SUPPORT_X32: 106*d78d3a22SFrançois Tigeot new_pcie_lanes = 32; 107*d78d3a22SFrançois Tigeot break; 108*d78d3a22SFrançois Tigeot default: 109*d78d3a22SFrançois Tigeot for (i = 0; i < 7; i++) { 110*d78d3a22SFrançois Tigeot if (ns_pcie_lanes == pcie_lanes[i]) { 111*d78d3a22SFrançois Tigeot if (pcie_lane_width_cap & (0x10000 << i)) { 112*d78d3a22SFrançois Tigeot break; 113*d78d3a22SFrançois Tigeot } else { 114*d78d3a22SFrançois Tigeot for (j = i - 1; j >= 0; j--) { 115*d78d3a22SFrançois Tigeot if (pcie_lane_width_cap & (0x10000 << j)) { 116*d78d3a22SFrançois Tigeot new_pcie_lanes = pcie_lanes[j]; 117*d78d3a22SFrançois Tigeot break; 118*d78d3a22SFrançois Tigeot } 119*d78d3a22SFrançois Tigeot } 120*d78d3a22SFrançois Tigeot 121*d78d3a22SFrançois Tigeot if (j < 0) { 122*d78d3a22SFrançois Tigeot for (j = i + 1; j < 7; j++) { 123*d78d3a22SFrançois Tigeot if (pcie_lane_width_cap & (0x10000 << j)) { 124*d78d3a22SFrançois Tigeot new_pcie_lanes = pcie_lanes[j]; 125*d78d3a22SFrançois Tigeot break; 126*d78d3a22SFrançois Tigeot } 127*d78d3a22SFrançois Tigeot } 128*d78d3a22SFrançois Tigeot if (j > 7) 129*d78d3a22SFrançois Tigeot printk(KERN_ERR "Cannot find a valid PCIE lane width!"); 130*d78d3a22SFrançois Tigeot } 131*d78d3a22SFrançois Tigeot } 132*d78d3a22SFrançois Tigeot break; 133*d78d3a22SFrançois Tigeot } 134*d78d3a22SFrançois Tigeot } 135*d78d3a22SFrançois Tigeot break; 136*d78d3a22SFrançois Tigeot } 137*d78d3a22SFrançois Tigeot 138*d78d3a22SFrançois Tigeot return new_pcie_lanes; 139*d78d3a22SFrançois Tigeot } 140*d78d3a22SFrançois Tigeot 141*d78d3a22SFrançois Tigeot #endif 142