high_speed_env_lib.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) Marvell International Ltd. and its affiliates
  4. */
  5. #include <common.h>
  6. #include <i2c.h>
  7. #include <spl.h>
  8. #include <asm/io.h>
  9. #include <asm/arch/cpu.h>
  10. #include <asm/arch/soc.h>
  11. #include <linux/delay.h>
  12. #include "high_speed_env_spec.h"
  13. #include "board_env_spec.h"
  14. #define SERDES_VERSION "2.1.5"
  15. #define ENDED_OK "High speed PHY - Ended Successfully\n"
  16. static const u8 serdes_cfg[][SERDES_LAST_UNIT] = BIN_SERDES_CFG;
  17. extern MV_BIN_SERDES_CFG *serdes_info_tbl[];
  18. extern u8 rd78460gp_twsi_dev[];
  19. extern u8 db88f78xx0rev2_twsi_dev[];
  20. u32 pex_cfg_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 offs);
  21. int pex_local_bus_num_set(u32 pex_if, u32 bus_num);
  22. int pex_local_dev_num_set(u32 pex_if, u32 dev_num);
  23. #define MV_BOARD_PEX_MODULE_ADDR 0x23
  24. #define MV_BOARD_PEX_MODULE_ID 1
  25. #define MV_BOARD_ETM_MODULE_ID 2
  26. #define PEX_MODULE_DETECT 1
  27. #define ETM_MODULE_DETECT 2
  28. #define PEX_MODE_GET(satr) ((satr & 0x6) >> 1)
  29. #define PEX_CAPABILITY_GET(satr, port) ((satr >> port) & 1)
  30. #define MV_PEX_UNIT_TO_IF(pex_unit) ((pex_unit < 3) ? (pex_unit * 4) : 9)
  31. /* Static parametes */
  32. static int config_module;
  33. static int switch_module;
  34. /* Local function */
  35. static u32 board_id_get(void)
  36. {
  37. #if defined(CONFIG_DB_88F78X60)
  38. return DB_88F78XX0_BP_ID;
  39. #elif defined(CONFIG_RD_88F78460_SERVER)
  40. return RD_78460_SERVER_ID;
  41. #elif defined(CONFIG_RD_78460_SERVER_REV2)
  42. return RD_78460_SERVER_REV2_ID;
  43. #elif defined(CONFIG_DB_78X60_PCAC)
  44. return DB_78X60_PCAC_ID;
  45. #elif defined(CONFIG_DB_88F78X60_REV2)
  46. return DB_88F78XX0_BP_REV2_ID;
  47. #elif defined(CONFIG_RD_78460_NAS)
  48. return RD_78460_NAS_ID;
  49. #elif defined(CONFIG_DB_78X60_AMC)
  50. return DB_78X60_AMC_ID;
  51. #elif defined(CONFIG_DB_78X60_PCAC_REV2)
  52. return DB_78X60_PCAC_REV2_ID;
  53. #elif defined(CONFIG_DB_784MP_GP)
  54. return DB_784MP_GP_ID;
  55. #elif defined(CONFIG_RD_78460_CUSTOMER)
  56. return RD_78460_CUSTOMER_ID;
  57. #else
  58. /*
  59. * Return 0 here for custom board as this should not be used
  60. * for custom boards.
  61. */
  62. return 0;
  63. #endif
  64. }
  65. __weak u8 board_sat_r_get(u8 dev_num, u8 reg)
  66. {
  67. u8 data;
  68. u8 *dev;
  69. u32 board_id = board_id_get();
  70. int ret;
  71. switch (board_id) {
  72. case DB_78X60_AMC_ID:
  73. case DB_78X60_PCAC_REV2_ID:
  74. case RD_78460_CUSTOMER_ID:
  75. case RD_78460_SERVER_ID:
  76. case RD_78460_SERVER_REV2_ID:
  77. case DB_78X60_PCAC_ID:
  78. return (0x1 << 1) | 1;
  79. case FPGA_88F78XX0_ID:
  80. case RD_78460_NAS_ID:
  81. return (0x0 << 1) | 1;
  82. case DB_784MP_GP_ID:
  83. dev = rd78460gp_twsi_dev;
  84. break;
  85. case DB_88F78XX0_BP_ID:
  86. case DB_88F78XX0_BP_REV2_ID:
  87. dev = db88f78xx0rev2_twsi_dev;
  88. break;
  89. default:
  90. return 0;
  91. }
  92. /* Read MPP module ID */
  93. i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
  94. ret = i2c_read(dev[dev_num], 0, 1, (u8 *)&data, 1);
  95. if (ret)
  96. return MV_ERROR;
  97. return data;
  98. }
  99. static int board_modules_scan(void)
  100. {
  101. u8 val;
  102. u32 board_id = board_id_get();
  103. int ret;
  104. /* Perform scan only for DB board */
  105. if ((board_id == DB_88F78XX0_BP_ID) ||
  106. (board_id == DB_88F78XX0_BP_REV2_ID)) {
  107. /* reset modules flags */
  108. config_module = 0;
  109. i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
  110. /* SERDES module (only PEX model is supported now) */
  111. ret = i2c_read(MV_BOARD_PEX_MODULE_ADDR, 0, 1, (u8 *)&val, 1);
  112. if (ret)
  113. return MV_ERROR;
  114. if (val == MV_BOARD_PEX_MODULE_ID)
  115. config_module = PEX_MODULE_DETECT;
  116. if (val == MV_BOARD_ETM_MODULE_ID)
  117. config_module = ETM_MODULE_DETECT;
  118. } else if (board_id == RD_78460_NAS_ID) {
  119. switch_module = 0;
  120. if ((reg_read(GPP_DATA_IN_REG(2)) & MV_GPP66) == 0x0)
  121. switch_module = 1;
  122. }
  123. return MV_OK;
  124. }
  125. u32 pex_max_unit_get(void)
  126. {
  127. /*
  128. * TODO:
  129. * Right now only MV78460 is supported. Other SoC's might need
  130. * a different value here.
  131. */
  132. return MV_PEX_MAX_UNIT;
  133. }
  134. u32 pex_max_if_get(void)
  135. {
  136. /*
  137. * TODO:
  138. * Right now only MV78460 is supported. Other SoC's might need
  139. * a different value here.
  140. */
  141. return MV_PEX_MAX_IF;
  142. }
  143. u8 board_cpu_freq_get(void)
  144. {
  145. u32 sar;
  146. u32 sar_msb;
  147. sar = reg_read(MPP_SAMPLE_AT_RESET(0));
  148. sar_msb = reg_read(MPP_SAMPLE_AT_RESET(1));
  149. return ((sar_msb & 0x100000) >> 17) | ((sar & 0xe00000) >> 21);
  150. }
  151. __weak MV_BIN_SERDES_CFG *board_serdes_cfg_get(void)
  152. {
  153. u32 board_id;
  154. u32 serdes_cfg_val = 0; /* default */
  155. board_id = board_id_get();
  156. switch (board_id) {
  157. case DB_784MP_GP_ID:
  158. serdes_cfg_val = 0;
  159. break;
  160. }
  161. return &serdes_info_tbl[board_id - BOARD_ID_BASE][serdes_cfg_val];
  162. }
  163. u16 ctrl_model_get(void)
  164. {
  165. /*
  166. * SoC version can't be autodetected. So we need to rely on a define
  167. * from the config system here.
  168. */
  169. #if defined(CONFIG_MV78230)
  170. return MV_78230_DEV_ID;
  171. #elif defined(CONFIG_MV78260)
  172. return MV_78260_DEV_ID;
  173. #else
  174. return MV_78460_DEV_ID;
  175. #endif
  176. }
  177. u32 get_line_cfg(u32 line_num, MV_BIN_SERDES_CFG *info)
  178. {
  179. if (line_num < 8)
  180. return (info->line0_7 >> (line_num << 2)) & 0xF;
  181. else
  182. return (info->line8_15 >> ((line_num - 8) << 2)) & 0xF;
  183. }
  184. static int serdes_max_lines_get(void)
  185. {
  186. switch (ctrl_model_get()) {
  187. case MV_78230_DEV_ID:
  188. return 7;
  189. case MV_78260_DEV_ID:
  190. return 12;
  191. case MV_78460_DEV_ID:
  192. return 16;
  193. }
  194. return 0;
  195. }
  196. /*
  197. * Tests have shown that on some boards the default width of the
  198. * configuration pulse for the PEX link detection might lead to
  199. * non-established PCIe links (link down). Especially under certain
  200. * conditions (higher temperature) and with specific PCIe devices.
  201. * To enable a board-specific detection pulse width this weak
  202. * array "serdes_pex_pulse_width[4]" is introduced which can be
  203. * overwritten if needed by a board-specific version. If the board
  204. * code does not provide a non-weak version of this variable, the
  205. * default value will be used. So nothing is changed from the
  206. * current setup on the supported board.
  207. */
  208. __weak u8 serdes_pex_pulse_width[4] = { 2, 2, 2, 2 };
  209. int serdes_phy_config(void)
  210. {
  211. int status = MV_OK;
  212. u32 line_cfg;
  213. u8 line_num;
  214. /* addr/value for each line @ every setup step */
  215. u32 addr[16][11], val[16][11];
  216. u8 pex_unit, pex_line_num;
  217. u8 sgmii_port = 0;
  218. u32 tmp;
  219. u32 in_direct;
  220. u8 max_serdes_lines;
  221. MV_BIN_SERDES_CFG *info;
  222. u8 satr11;
  223. u8 sata_port;
  224. u8 freq;
  225. u8 device_rev;
  226. u32 rx_high_imp_mode;
  227. u16 ctrl_mode;
  228. u32 pex_if;
  229. u32 pex_if_num;
  230. /*
  231. * Get max. serdes lines count
  232. */
  233. max_serdes_lines = serdes_max_lines_get();
  234. if (max_serdes_lines == 0)
  235. return MV_OK;
  236. satr11 = board_sat_r_get(1, 1);
  237. if ((u8) MV_ERROR == (u8) satr11)
  238. return MV_ERROR;
  239. board_modules_scan();
  240. memset(addr, 0, sizeof(addr));
  241. memset(val, 0, sizeof(val));
  242. /* Check if DRAM is already initialized */
  243. if (reg_read(REG_BOOTROM_ROUTINE_ADDR) &
  244. (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) {
  245. DEBUG_INIT_S("High speed PHY - Version: ");
  246. DEBUG_INIT_S(SERDES_VERSION);
  247. DEBUG_INIT_S(" - 2nd boot - Skip\n");
  248. return MV_OK;
  249. }
  250. DEBUG_INIT_S("High speed PHY - Version: ");
  251. DEBUG_INIT_S(SERDES_VERSION);
  252. DEBUG_INIT_S(" (COM-PHY-V20)\n");
  253. /*
  254. * AVS : disable AVS for frequency less than 1333
  255. */
  256. freq = board_cpu_freq_get();
  257. device_rev = mv_ctrl_rev_get();
  258. if (device_rev == 2) { /* for B0 only */
  259. u32 cpu_avs;
  260. u8 fabric_freq;
  261. cpu_avs = reg_read(CPU_AVS_CONTROL2_REG);
  262. DEBUG_RD_REG(CPU_AVS_CONTROL2_REG, cpu_avs);
  263. cpu_avs &= ~(1 << 9);
  264. if ((0x4 == freq) || (0xB == freq)) {
  265. u32 tmp2;
  266. tmp2 = reg_read(CPU_AVS_CONTROL0_REG);
  267. DEBUG_RD_REG(CPU_AVS_CONTROL0_REG, tmp2);
  268. /* cpu upper limit = 1.1V cpu lower limit = 0.9125V */
  269. tmp2 |= 0x0FF;
  270. reg_write(CPU_AVS_CONTROL0_REG, tmp2);
  271. DEBUG_WR_REG(CPU_AVS_CONTROL0_REG, tmp2);
  272. cpu_avs |= (1 << 9); /* cpu avs enable */
  273. cpu_avs |= (1 << 18); /* AvsAvddDetEn enable */
  274. fabric_freq = (reg_read(MPP_SAMPLE_AT_RESET(0)) &
  275. SAR0_FABRIC_FREQ_MASK) >> SAR0_FABRIC_FREQ_OFFSET;
  276. if ((0xB == freq) && (5 == fabric_freq)) {
  277. u32 core_avs;
  278. core_avs = reg_read(CORE_AVS_CONTROL_0REG);
  279. DEBUG_RD_REG(CORE_AVS_CONTROL_0REG, core_avs);
  280. /*
  281. * Set core lower limit = 0.9V &
  282. * core upper limit = 0.9125V
  283. */
  284. core_avs &= ~(0xff);
  285. core_avs |= 0x0E;
  286. reg_write(CORE_AVS_CONTROL_0REG, core_avs);
  287. DEBUG_WR_REG(CORE_AVS_CONTROL_0REG, core_avs);
  288. core_avs = reg_read(CORE_AVS_CONTROL_2REG);
  289. DEBUG_RD_REG(CORE_AVS_CONTROL_2REG, core_avs);
  290. core_avs |= (1 << 9); /* core AVS enable */
  291. reg_write(CORE_AVS_CONTROL_2REG, core_avs);
  292. DEBUG_WR_REG(CORE_AVS_CONTROL_2REG, core_avs);
  293. tmp2 = reg_read(GENERAL_PURPOSE_RESERVED0_REG);
  294. DEBUG_RD_REG(GENERAL_PURPOSE_RESERVED0_REG,
  295. tmp2);
  296. tmp2 |= 0x1; /* AvsCoreAvddDetEn enable */
  297. reg_write(GENERAL_PURPOSE_RESERVED0_REG, tmp2);
  298. DEBUG_WR_REG(GENERAL_PURPOSE_RESERVED0_REG,
  299. tmp2);
  300. }
  301. }
  302. reg_write(CPU_AVS_CONTROL2_REG, cpu_avs);
  303. DEBUG_WR_REG(CPU_AVS_CONTROL2_REG, cpu_avs);
  304. }
  305. info = board_serdes_cfg_get();
  306. if (info == NULL) {
  307. DEBUG_INIT_S("Hight speed PHY Error #1\n");
  308. return MV_ERROR;
  309. }
  310. DEBUG_INIT_FULL_S("info->line0_7= 0x");
  311. DEBUG_INIT_FULL_D(info->line0_7, 8);
  312. DEBUG_INIT_FULL_S(" info->line8_15= 0x");
  313. DEBUG_INIT_FULL_D(info->line8_15, 8);
  314. DEBUG_INIT_FULL_S("\n");
  315. if (config_module & ETM_MODULE_DETECT) { /* step 0.9 ETM */
  316. DEBUG_INIT_FULL_S("ETM module detect Step 0.9:\n");
  317. reg_write(SERDES_LINE_MUX_REG_0_7, 0x11111111);
  318. DEBUG_WR_REG(SERDES_LINE_MUX_REG_0_7, 0x11111111);
  319. info->pex_mode[1] = PEX_BUS_DISABLED; /* pex unit 1 is configure for ETM */
  320. mdelay(100);
  321. reg_write(PEX_PHY_ACCESS_REG(1), (0x002 << 16) | 0xf44d); /* SETM0 - start calibration */
  322. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x002 << 16) | 0xf44d); /* SETM0 - start calibration */
  323. reg_write(PEX_PHY_ACCESS_REG(1), (0x302 << 16) | 0xf44d); /* SETM1 - start calibration */
  324. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x302 << 16) | 0xf44d); /* SETM1 - start calibration */
  325. reg_write(PEX_PHY_ACCESS_REG(1), (0x001 << 16) | 0xf801); /* SETM0 - SATA mode & 25MHz ref clk */
  326. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x001 << 16) | 0xf801); /* SETM0 - SATA mode & 25MHz ref clk */
  327. reg_write(PEX_PHY_ACCESS_REG(1), (0x301 << 16) | 0xf801); /* SETM1 - SATA mode & 25MHz ref clk */
  328. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x301 << 16) | 0xf801); /* SETM1 - SATA mode & 25MHz ref clk */
  329. reg_write(PEX_PHY_ACCESS_REG(1), (0x011 << 16) | 0x0BFF); /* SETM0 - G3 full swing AMP */
  330. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x011 << 16) | 0x0BFF); /* SETM0 - G3 full swing AMP */
  331. reg_write(PEX_PHY_ACCESS_REG(1), (0x311 << 16) | 0x0BFF); /* SETM1 - G3 full swing AMP */
  332. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x311 << 16) | 0x0BFF); /* SETM1 - G3 full swing AMP */
  333. reg_write(PEX_PHY_ACCESS_REG(1), (0x023 << 16) | 0x0800); /* SETM0 - 40 data bit width */
  334. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x023 << 16) | 0x0800); /* SETM0 - 40 data bit width */
  335. reg_write(PEX_PHY_ACCESS_REG(1), (0x323 << 16) | 0x0800); /* SETM1 - 40 data bit width */
  336. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x323 << 16) | 0x0800); /* SETM1 - 40 data bit width */
  337. reg_write(PEX_PHY_ACCESS_REG(1), (0x046 << 16) | 0x0400); /* lane0(serdes4) */
  338. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x046 << 16) | 0x0400); /* lane0(serdes4) */
  339. reg_write(PEX_PHY_ACCESS_REG(1), (0x346 << 16) | 0x0400); /* lane3(serdes7) */
  340. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(1), (0x346 << 16) | 0x0400); /* lane3(serdes7) */
  341. }
  342. /* STEP -1 [PEX-Only] First phase of PEX-PIPE Configuration: */
  343. DEBUG_INIT_FULL_S("Step 1: First phase of PEX-PIPE Configuration\n");
  344. for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) {
  345. if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED)
  346. continue;
  347. /* 1. GLOB_CLK_CTRL Reset and Clock Control */
  348. reg_write(PEX_PHY_ACCESS_REG(pex_unit), (0xC1 << 16) | 0x25);
  349. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), (0xC1 << 16) | 0x25);
  350. /* 2. GLOB_TEST_CTRL Test Mode Control */
  351. if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) {
  352. reg_write(PEX_PHY_ACCESS_REG(pex_unit),
  353. (0xC2 << 16) | 0x200);
  354. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),
  355. (0xC2 << 16) | 0x200);
  356. }
  357. /* 3. GLOB_CLK_SRC_LO Clock Source Low */
  358. if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X1) {
  359. reg_write(PEX_PHY_ACCESS_REG(pex_unit),
  360. (0xC3 << 16) | 0x0F);
  361. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),
  362. (0xC3 << 16) | 0x0F);
  363. }
  364. reg_write(PEX_PHY_ACCESS_REG(pex_unit), (0xC5 << 16) | 0x11F);
  365. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),
  366. (0xC5 << 16) | 0x11F);
  367. }
  368. /*
  369. * 2 Configure the desire PIN_PHY_GEN and do power down to the PU_PLL,
  370. * PU_RX,PU_TX. (bits[12:5])
  371. */
  372. DEBUG_INIT_FULL_S("Step 2: Configure the desire PIN_PHY_GEN\n");
  373. for (line_num = 0; line_num < max_serdes_lines; line_num++) {
  374. line_cfg = get_line_cfg(line_num, info);
  375. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED])
  376. continue;
  377. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX])
  378. continue;
  379. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) {
  380. switch (line_num) {
  381. case 4:
  382. case 6:
  383. sata_port = 0;
  384. break;
  385. case 5:
  386. sata_port = 1;
  387. break;
  388. default:
  389. DEBUG_INIT_C
  390. ("SATA port error for serdes line: ",
  391. line_num, 2);
  392. return MV_ERROR;
  393. }
  394. tmp = reg_read(SATA_LP_PHY_EXT_CTRL_REG(sata_port));
  395. DEBUG_RD_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp);
  396. tmp &= ~((0x1ff << 5) | 0x7);
  397. tmp |= ((info->bus_speed & (1 << line_num)) != 0) ?
  398. (0x11 << 5) : 0x0;
  399. reg_write(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp);
  400. DEBUG_WR_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp);
  401. }
  402. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) {
  403. /*
  404. * 4) Configure the desire PIN_PHY_GEN and do power
  405. * down to the PU_PLL,PU_RX,PU_TX. (bits[12:5])
  406. */
  407. tmp = reg_read(SGMII_SERDES_CFG_REG(0));
  408. DEBUG_RD_REG(SGMII_SERDES_CFG_REG(0), tmp);
  409. tmp &= ~((0x1ff << 5) | 0x7);
  410. tmp |= 0x660;
  411. reg_write(SGMII_SERDES_CFG_REG(0), tmp);
  412. DEBUG_WR_REG(SGMII_SERDES_CFG_REG(0), tmp);
  413. continue;
  414. }
  415. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII0])
  416. sgmii_port = 0;
  417. else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII1])
  418. sgmii_port = 1;
  419. else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII2])
  420. sgmii_port = 2;
  421. else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII3])
  422. sgmii_port = 3;
  423. else
  424. continue;
  425. tmp = reg_read(SGMII_SERDES_CFG_REG(sgmii_port));
  426. DEBUG_RD_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp);
  427. tmp &= ~((0x1ff << 5) | 0x7);
  428. tmp |= (((info->bus_speed & (1 << line_num)) != 0) ?
  429. (0x88 << 5) : (0x66 << 5));
  430. reg_write(SGMII_SERDES_CFG_REG(sgmii_port), tmp);
  431. DEBUG_WR_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp);
  432. }
  433. /* Step 3 - QSGMII enable */
  434. DEBUG_INIT_FULL_S("Step 3 QSGMII enable\n");
  435. for (line_num = 0; line_num < max_serdes_lines; line_num++) {
  436. line_cfg = get_line_cfg(line_num, info);
  437. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) {
  438. /* QSGMII Active bit set to true */
  439. tmp = reg_read(QSGMII_CONTROL_1_REG);
  440. DEBUG_RD_REG(QSGMII_CONTROL_1_REG, tmp);
  441. tmp |= (1 << 30);
  442. #ifdef ERRATA_GL_6572255
  443. tmp |= (1 << 27);
  444. #endif
  445. reg_write(QSGMII_CONTROL_1_REG, tmp);
  446. DEBUG_WR_REG(QSGMII_CONTROL_1_REG, tmp);
  447. }
  448. }
  449. /* Step 4 - configure SERDES MUXes */
  450. DEBUG_INIT_FULL_S("Step 4: Configure SERDES MUXes\n");
  451. if (config_module & ETM_MODULE_DETECT) {
  452. reg_write(SERDES_LINE_MUX_REG_0_7, 0x40041111);
  453. DEBUG_WR_REG(SERDES_LINE_MUX_REG_0_7, 0x40041111);
  454. } else {
  455. reg_write(SERDES_LINE_MUX_REG_0_7, info->line0_7);
  456. DEBUG_WR_REG(SERDES_LINE_MUX_REG_0_7, info->line0_7);
  457. }
  458. reg_write(SERDES_LINE_MUX_REG_8_15, info->line8_15);
  459. DEBUG_WR_REG(SERDES_LINE_MUX_REG_8_15, info->line8_15);
  460. /* Step 5: Activate the RX High Impedance Mode */
  461. DEBUG_INIT_FULL_S("Step 5: Activate the RX High Impedance Mode\n");
  462. rx_high_imp_mode = 0x8080;
  463. if (device_rev == 2) /* for B0 only */
  464. rx_high_imp_mode |= 4;
  465. for (line_num = 0; line_num < max_serdes_lines; line_num++) {
  466. /* for each serdes lane */
  467. DEBUG_INIT_FULL_S("SERDES ");
  468. DEBUG_INIT_FULL_D_10(line_num, 2);
  469. line_cfg = get_line_cfg(line_num, info);
  470. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED]) {
  471. DEBUG_INIT_FULL_S(" unconnected ***\n");
  472. continue;
  473. }
  474. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) {
  475. pex_unit = line_num >> 2;
  476. pex_line_num = line_num % 4;
  477. DEBUG_INIT_FULL_S(" - PEX unit ");
  478. DEBUG_INIT_FULL_D_10(pex_unit, 1);
  479. DEBUG_INIT_FULL_S(" line= ");
  480. DEBUG_INIT_FULL_D_10(pex_line_num, 1);
  481. DEBUG_INIT_FULL_S("\n");
  482. /* Needed for PEX_PHY_ACCESS_REG macro */
  483. if ((line_num > 7) &&
  484. (info->pex_mode[3] == PEX_BUS_MODE_X8))
  485. /* lines 8 - 15 are belong to PEX3 in x8 mode */
  486. pex_unit = 3;
  487. if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED)
  488. continue;
  489. /*
  490. * 8) Activate the RX High Impedance Mode field
  491. * (bit [2]) in register /PCIe_USB Control (Each MAC
  492. * contain different Access to reach its
  493. * Serdes-Regfile).
  494. * [PEX-Only] Set bit[12]: The analog part latches idle
  495. * if PU_TX = 1 and PU_PLL =1.
  496. */
  497. /* Termination enable */
  498. if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X1) {
  499. in_direct = (0x48 << 16) | (pex_line_num << 24) |
  500. 0x1000 | rx_high_imp_mode; /* x1 */
  501. } else if ((info->pex_mode[pex_unit] ==
  502. PEX_BUS_MODE_X4) && (pex_line_num == 0))
  503. in_direct = (0x48 << 16) | (pex_line_num << 24) |
  504. 0x1000 | (rx_high_imp_mode & 0xff); /* x4 */
  505. else
  506. in_direct = 0;
  507. if (in_direct) {
  508. reg_write(PEX_PHY_ACCESS_REG(pex_unit),
  509. in_direct);
  510. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),
  511. in_direct);
  512. }
  513. continue;
  514. }
  515. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) {
  516. /*
  517. * port 0 for serdes lines 4,6, and port 1 for
  518. * serdes lines 5
  519. */
  520. sata_port = line_num & 1;
  521. DEBUG_INIT_FULL_S(" - SATA port ");
  522. DEBUG_INIT_FULL_D_10(sata_port, 2);
  523. DEBUG_INIT_FULL_S("\n");
  524. reg_write(SATA_COMPHY_CTRL_REG(sata_port),
  525. rx_high_imp_mode);
  526. DEBUG_WR_REG(SATA_COMPHY_CTRL_REG(sata_port),
  527. rx_high_imp_mode);
  528. continue;
  529. }
  530. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) {
  531. DEBUG_INIT_FULL_S(" - QSGMII\n");
  532. reg_write(SGMII_COMPHY_CTRL_REG(0), rx_high_imp_mode);
  533. DEBUG_WR_REG(SGMII_COMPHY_CTRL_REG(0),
  534. rx_high_imp_mode);
  535. continue;
  536. }
  537. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII0])
  538. sgmii_port = 0;
  539. else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII1])
  540. sgmii_port = 1;
  541. else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII2])
  542. sgmii_port = 2;
  543. else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII3])
  544. sgmii_port = 3;
  545. else
  546. continue;
  547. DEBUG_INIT_FULL_S(" - SGMII port ");
  548. DEBUG_INIT_FULL_D_10(sgmii_port, 2);
  549. DEBUG_INIT_FULL_S("\n");
  550. reg_write(SGMII_COMPHY_CTRL_REG(sgmii_port), rx_high_imp_mode);
  551. DEBUG_WR_REG(SGMII_COMPHY_CTRL_REG(sgmii_port),
  552. rx_high_imp_mode);
  553. } /* for each serdes lane */
  554. /* Step 6 [PEX-Only] PEX-Main configuration (X4 or X1): */
  555. DEBUG_INIT_FULL_S("Step 6: [PEX-Only] PEX-Main configuration (X4 or X1)\n");
  556. tmp = reg_read(SOC_CTRL_REG);
  557. DEBUG_RD_REG(SOC_CTRL_REG, tmp);
  558. tmp &= 0x200;
  559. if (info->pex_mode[0] == PEX_BUS_MODE_X1)
  560. tmp |= PCIE0_QUADX1_EN;
  561. if (info->pex_mode[1] == PEX_BUS_MODE_X1)
  562. tmp |= PCIE1_QUADX1_EN;
  563. if (((reg_read(MPP_SAMPLE_AT_RESET(0)) & PEX_CLK_100MHZ_MASK) >>
  564. PEX_CLK_100MHZ_OFFSET) == 0x1)
  565. tmp |= (PCIE0_CLK_OUT_EN_MASK | PCIE1_CLK_OUT_EN_MASK);
  566. reg_write(SOC_CTRL_REG, tmp);
  567. DEBUG_WR_REG(SOC_CTRL_REG, tmp);
  568. /* 6.2 PCI Express Link Capabilities */
  569. DEBUG_INIT_FULL_S("Step 6.2: [PEX-Only] PCI Express Link Capabilities\n");
  570. for (line_num = 0; line_num < max_serdes_lines; line_num++) {
  571. line_cfg = get_line_cfg(line_num, info);
  572. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) {
  573. /*
  574. * PCI Express Control
  575. * 0xX1A00 [0]:
  576. * 0x0 X4-Link.
  577. * 0x1 X1-Link
  578. */
  579. pex_unit = line_num >> 2;
  580. pex_if = MV_SERDES_NUM_TO_PEX_NUM(line_num);
  581. if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED)
  582. continue;
  583. /* set Common Clock Configuration */
  584. tmp = reg_read(PEX_LINK_CTRL_STATUS_REG(pex_if));
  585. DEBUG_RD_REG(PEX_LINK_CTRL_STATUS_REG(pex_if), tmp);
  586. tmp |= (1 << 6);
  587. reg_write(PEX_LINK_CTRL_STATUS_REG(pex_if), tmp);
  588. DEBUG_WR_REG(PEX_LINK_CTRL_STATUS_REG(pex_if), tmp);
  589. tmp = reg_read(PEX_LINK_CAPABILITIES_REG(pex_if));
  590. DEBUG_RD_REG(PEX_LINK_CAPABILITIES_REG(pex_if), tmp);
  591. tmp &= ~(0x3FF);
  592. if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X1)
  593. tmp |= (0x1 << 4);
  594. if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)
  595. tmp |= (0x4 << 4);
  596. if (0 == PEX_CAPABILITY_GET(satr11, pex_unit))
  597. tmp |= 0x1;
  598. else
  599. tmp |= 0x2;
  600. DEBUG_INIT_FULL_S("Step 6.2: PEX ");
  601. DEBUG_INIT_FULL_D(pex_if, 1);
  602. DEBUG_INIT_FULL_C(" set GEN", (tmp & 3), 1);
  603. reg_write(PEX_LINK_CAPABILITIES_REG(pex_if), tmp);
  604. DEBUG_WR_REG(PEX_LINK_CAPABILITIES_REG(pex_if), tmp);
  605. /*
  606. * If pex is X4, no need to pass thru the other
  607. * 3X1 serdes lines
  608. */
  609. if (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4)
  610. line_num += 3;
  611. }
  612. }
  613. /*
  614. * Step 7 [PEX-X4 Only] To create PEX-Link that contain 4-lanes you
  615. * need to config the register SOC_Misc/General Purpose2
  616. * (Address= 182F8)
  617. */
  618. DEBUG_INIT_FULL_S("Step 7: [PEX-X4 Only] To create PEX-Link\n");
  619. tmp = reg_read(GEN_PURP_RES_2_REG);
  620. DEBUG_RD_REG(GEN_PURP_RES_2_REG, tmp);
  621. tmp &= 0xFFFF0000;
  622. if (info->pex_mode[0] == PEX_BUS_MODE_X4)
  623. tmp |= 0x0000000F;
  624. if (info->pex_mode[1] == PEX_BUS_MODE_X4)
  625. tmp |= 0x000000F0;
  626. if (info->pex_mode[2] == PEX_BUS_MODE_X4)
  627. tmp |= 0x00000F00;
  628. if (info->pex_mode[3] == PEX_BUS_MODE_X4)
  629. tmp |= 0x0000F000;
  630. reg_write(GEN_PURP_RES_2_REG, tmp);
  631. DEBUG_WR_REG(GEN_PURP_RES_2_REG, tmp);
  632. /* Steps 8 , 9 ,10 - use prepared REG addresses and values */
  633. DEBUG_INIT_FULL_S("Steps 7,8,9,10 and 11\n");
  634. /* Prepare PHY parameters for each step according to MUX selection */
  635. for (line_num = 0; line_num < max_serdes_lines; line_num++) {
  636. /* for each serdes lane */
  637. line_cfg = get_line_cfg(line_num, info);
  638. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED])
  639. continue;
  640. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) {
  641. pex_unit = line_num >> 2;
  642. pex_line_num = line_num % 4;
  643. if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED)
  644. continue;
  645. /*
  646. * 8) Configure the desire PHY_MODE (bits [7:5])
  647. * and REF_FREF_SEL (bits[4:0]) in the register Power
  648. * and PLL Control (Each MAC contain different Access
  649. * to reach its Serdes-Regfile).
  650. */
  651. if (((info->pex_mode[pex_unit] == PEX_BUS_MODE_X4) &&
  652. (0 == pex_line_num))
  653. || ((info->pex_mode[pex_unit] == PEX_BUS_MODE_X1))) {
  654. reg_write(PEX_PHY_ACCESS_REG(pex_unit),
  655. (0x01 << 16) | (pex_line_num << 24) |
  656. 0xFC60);
  657. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),
  658. (0x01 << 16) | (pex_line_num << 24)
  659. | 0xFC60);
  660. /*
  661. * Step 8.1: [PEX-Only] Configure Max PLL Rate
  662. * (bit 8 in KVCO Calibration Control and
  663. * bits[10:9] in
  664. */
  665. /* Use Maximum PLL Rate(Bit 8) */
  666. reg_write(PEX_PHY_ACCESS_REG(pex_unit),
  667. (0x02 << 16) | (1 << 31) |
  668. (pex_line_num << 24)); /* read command */
  669. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),
  670. (0x02 << 16) | (1 << 31) |
  671. (pex_line_num << 24));
  672. tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit));
  673. DEBUG_RD_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp);
  674. tmp &= ~(1 << 31);
  675. tmp |= (1 << 8);
  676. reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp);
  677. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp);
  678. /* Use Maximum PLL Rate(Bits [10:9]) */
  679. reg_write(PEX_PHY_ACCESS_REG(pex_unit),
  680. (0x81 << 16) | (1 << 31) |
  681. (pex_line_num << 24)); /* read command */
  682. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),
  683. (0x81 << 16) | (1 << 31) |
  684. (pex_line_num << 24));
  685. tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit));
  686. DEBUG_RD_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp);
  687. tmp &= ~(1 << 31);
  688. tmp |= (3 << 9);
  689. reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp);
  690. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit), tmp);
  691. }
  692. continue;
  693. }
  694. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) {
  695. /*
  696. * Port 0 for serdes lines 4,6, and port 1 for serdes
  697. * lines 5
  698. */
  699. sata_port = line_num & 1;
  700. /*
  701. * 8) Configure the desire PHY_MODE (bits [7:5]) and
  702. * REF_FREF_SEL (bits[4:0]) in the register Power
  703. * and PLL Control (Each MAC contain different Access
  704. * to reach its Serdes-Regfile).
  705. */
  706. reg_write(SATA_PWR_PLL_CTRL_REG(sata_port), 0xF801);
  707. DEBUG_WR_REG(SATA_PWR_PLL_CTRL_REG(sata_port), 0xF801);
  708. /* 9) Configure the desire SEL_BITS */
  709. reg_write(SATA_DIG_LP_ENA_REG(sata_port), 0x400);
  710. DEBUG_WR_REG(SATA_DIG_LP_ENA_REG(sata_port), 0x400);
  711. /* 10) Configure the desire REFCLK_SEL */
  712. reg_write(SATA_REF_CLK_SEL_REG(sata_port), 0x400);
  713. DEBUG_WR_REG(SATA_REF_CLK_SEL_REG(sata_port), 0x400);
  714. /* 11) Power up to the PU_PLL,PU_RX,PU_TX. */
  715. tmp = reg_read(SATA_LP_PHY_EXT_CTRL_REG(sata_port));
  716. DEBUG_RD_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp);
  717. tmp |= 7;
  718. reg_write(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp);
  719. DEBUG_WR_REG(SATA_LP_PHY_EXT_CTRL_REG(sata_port), tmp);
  720. continue;
  721. }
  722. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_QSGMII]) {
  723. /*
  724. * 8) Configure the desire PHY_MODE (bits [7:5])
  725. * and REF_FREF_SEL (bits[4:0]) in the register
  726. */
  727. reg_write(SGMII_PWR_PLL_CTRL_REG(0), 0xF881);
  728. DEBUG_WR_REG(SGMII_PWR_PLL_CTRL_REG(0), 0xF881);
  729. /*
  730. * 9) Configure the desire SEL_BITS (bits [11:0]
  731. * in register
  732. */
  733. reg_write(SGMII_DIG_LP_ENA_REG(0), 0x400);
  734. DEBUG_WR_REG(SGMII_DIG_LP_ENA_REG(0), 0x400);
  735. /*
  736. * 10) Configure the desire REFCLK_SEL (bit [10])
  737. * in register
  738. */
  739. reg_write(SGMII_REF_CLK_SEL_REG(0), 0x400);
  740. DEBUG_WR_REG(SGMII_REF_CLK_SEL_REG(0), 0x400);
  741. /* 11) Power up to the PU_PLL,PU_RX,PU_TX. */
  742. tmp = reg_read(SGMII_SERDES_CFG_REG(0));
  743. DEBUG_RD_REG(SGMII_SERDES_CFG_REG(0), tmp);
  744. tmp |= 7;
  745. reg_write(SGMII_SERDES_CFG_REG(0), tmp);
  746. DEBUG_WR_REG(SGMII_SERDES_CFG_REG(0), tmp);
  747. continue;
  748. }
  749. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII0])
  750. sgmii_port = 0;
  751. else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII1])
  752. sgmii_port = 1;
  753. else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII2])
  754. sgmii_port = 2;
  755. else if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SGMII3])
  756. sgmii_port = 3;
  757. else
  758. continue;
  759. /*
  760. * 8) Configure the desire PHY_MODE (bits [7:5]) and
  761. * REF_FREF_SEL (bits[4:0]) in the register
  762. */
  763. reg_write(SGMII_PWR_PLL_CTRL_REG(sgmii_port), 0xF881);
  764. DEBUG_WR_REG(SGMII_PWR_PLL_CTRL_REG(sgmii_port), 0xF881);
  765. /* 9) Configure the desire SEL_BITS (bits [11:0] in register */
  766. reg_write(SGMII_DIG_LP_ENA_REG(sgmii_port), 0);
  767. DEBUG_WR_REG(SGMII_DIG_LP_ENA_REG(sgmii_port), 0);
  768. /* 10) Configure the desire REFCLK_SEL (bit [10]) in register */
  769. reg_write(SGMII_REF_CLK_SEL_REG(sgmii_port), 0x400);
  770. DEBUG_WR_REG(SGMII_REF_CLK_SEL_REG(sgmii_port), 0x400);
  771. /* 11) Power up to the PU_PLL,PU_RX,PU_TX. */
  772. tmp = reg_read(SGMII_SERDES_CFG_REG(sgmii_port));
  773. DEBUG_RD_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp);
  774. tmp |= 7;
  775. reg_write(SGMII_SERDES_CFG_REG(sgmii_port), tmp);
  776. DEBUG_WR_REG(SGMII_SERDES_CFG_REG(sgmii_port), tmp);
  777. } /* for each serdes lane */
  778. /* Step 12 [PEX-Only] Last phase of PEX-PIPE Configuration */
  779. DEBUG_INIT_FULL_S("Steps 12: [PEX-Only] Last phase of PEX-PIPE Configuration\n");
  780. for (line_num = 0; line_num < max_serdes_lines; line_num++) {
  781. /* for each serdes lane */
  782. line_cfg = get_line_cfg(line_num, info);
  783. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED])
  784. continue;
  785. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX]) {
  786. pex_unit = line_num >> 2;
  787. pex_line_num = line_num % 4;
  788. if (0 == pex_line_num) {
  789. /*
  790. * Configure the detection pulse with before
  791. * the reset is deasserted
  792. */
  793. /* Read the old value (indirect access) */
  794. reg_write(PEX_PHY_ACCESS_REG(pex_unit),
  795. (0x48 << 16) | (1 << 31) |
  796. (pex_line_num << 24));
  797. tmp = reg_read(PEX_PHY_ACCESS_REG(pex_unit));
  798. tmp &= ~(1 << 31); /* Clear read */
  799. tmp &= ~(3 << 6); /* Mask width */
  800. /* Insert new detection pulse width */
  801. tmp |= serdes_pex_pulse_width[pex_unit] << 6;
  802. /* Write value back */
  803. reg_write(PEX_PHY_ACCESS_REG(pex_unit), tmp);
  804. reg_write(PEX_PHY_ACCESS_REG(pex_unit),
  805. (0xC1 << 16) | 0x24);
  806. DEBUG_WR_REG(PEX_PHY_ACCESS_REG(pex_unit),
  807. (0xC1 << 16) | 0x24);
  808. }
  809. }
  810. }
  811. /*--------------------------------------------------------------*/
  812. /* Step 13: Wait 15ms before checking results */
  813. DEBUG_INIT_FULL_S("Steps 13: Wait 15ms before checking results");
  814. mdelay(15);
  815. tmp = 20;
  816. while (tmp) {
  817. status = MV_OK;
  818. for (line_num = 0; line_num < max_serdes_lines; line_num++) {
  819. u32 tmp;
  820. line_cfg = get_line_cfg(line_num, info);
  821. if (line_cfg ==
  822. serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED])
  823. continue;
  824. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_PEX])
  825. continue;
  826. if (line_cfg == serdes_cfg[line_num][SERDES_UNIT_SATA]) {
  827. /*
  828. * Port 0 for serdes lines 4,6, and port 1
  829. * for serdes lines 5
  830. */
  831. sata_port = line_num & 1;
  832. tmp =
  833. reg_read(SATA_LP_PHY_EXT_STAT_REG
  834. (sata_port));
  835. DEBUG_RD_REG(SATA_LP_PHY_EXT_STAT_REG
  836. (sata_port), tmp);
  837. if ((tmp & 0x7) != 0x7)
  838. status = MV_ERROR;
  839. continue;
  840. }
  841. if (line_cfg ==
  842. serdes_cfg[line_num][SERDES_UNIT_QSGMII]) {
  843. tmp = reg_read(SGMII_SERDES_STAT_REG(0));
  844. DEBUG_RD_REG(SGMII_SERDES_STAT_REG(0), tmp);
  845. if ((tmp & 0x7) != 0x7)
  846. status = MV_ERROR;
  847. continue;
  848. }
  849. if (line_cfg ==
  850. serdes_cfg[line_num][SERDES_UNIT_SGMII0])
  851. sgmii_port = 0;
  852. else if (line_cfg ==
  853. serdes_cfg[line_num][SERDES_UNIT_SGMII1])
  854. sgmii_port = 1;
  855. else if (line_cfg ==
  856. serdes_cfg[line_num][SERDES_UNIT_SGMII2])
  857. sgmii_port = 2;
  858. else if (line_cfg ==
  859. serdes_cfg[line_num][SERDES_UNIT_SGMII3])
  860. sgmii_port = 3;
  861. else
  862. continue;
  863. tmp = reg_read(SGMII_SERDES_STAT_REG(sgmii_port));
  864. DEBUG_RD_REG(SGMII_SERDES_STAT_REG(sgmii_port), tmp);
  865. if ((tmp & 0x7) != 0x7)
  866. status = MV_ERROR;
  867. }
  868. if (status == MV_OK)
  869. break;
  870. mdelay(5);
  871. tmp--;
  872. }
  873. /*
  874. * Step14 [PEX-Only] In order to configure RC/EP mode please write
  875. * to register 0x0060 bits
  876. */
  877. DEBUG_INIT_FULL_S("Steps 14: [PEX-Only] In order to configure\n");
  878. for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) {
  879. if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED)
  880. continue;
  881. tmp =
  882. reg_read(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)));
  883. DEBUG_RD_REG(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)),
  884. tmp);
  885. tmp &= ~(0xf << 20);
  886. if (info->pex_type == MV_PEX_ROOT_COMPLEX)
  887. tmp |= (0x4 << 20);
  888. else
  889. tmp |= (0x1 << 20);
  890. reg_write(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)),
  891. tmp);
  892. DEBUG_WR_REG(PEX_CAPABILITIES_REG(MV_PEX_UNIT_TO_IF(pex_unit)),
  893. tmp);
  894. }
  895. /*
  896. * Step 15 [PEX-Only] Only for EP mode set to Zero bits 19 and 16 of
  897. * register 0x1a60
  898. */
  899. DEBUG_INIT_FULL_S("Steps 15: [PEX-Only] In order to configure\n");
  900. for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) {
  901. if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED)
  902. continue;
  903. if (info->pex_type == MV_PEX_END_POINT) {
  904. tmp =
  905. reg_read(PEX_DBG_CTRL_REG
  906. (MV_PEX_UNIT_TO_IF(pex_unit)));
  907. DEBUG_RD_REG(PEX_DBG_CTRL_REG
  908. (MV_PEX_UNIT_TO_IF(pex_unit)), tmp);
  909. tmp &= 0xfff6ffff;
  910. reg_write(PEX_DBG_CTRL_REG(MV_PEX_UNIT_TO_IF(pex_unit)),
  911. tmp);
  912. DEBUG_WR_REG(PEX_DBG_CTRL_REG
  913. (MV_PEX_UNIT_TO_IF(pex_unit)), tmp);
  914. }
  915. }
  916. if (info->serdes_m_phy_change) {
  917. MV_SERDES_CHANGE_M_PHY *serdes_m_phy_change;
  918. u32 bus_speed;
  919. for (line_num = 0; line_num < max_serdes_lines; line_num++) {
  920. line_cfg = get_line_cfg(line_num, info);
  921. if (line_cfg ==
  922. serdes_cfg[line_num][SERDES_UNIT_UNCONNECTED])
  923. continue;
  924. serdes_m_phy_change = info->serdes_m_phy_change;
  925. bus_speed = info->bus_speed & (1 << line_num);
  926. while (serdes_m_phy_change->type !=
  927. SERDES_UNIT_UNCONNECTED) {
  928. switch (serdes_m_phy_change->type) {
  929. case SERDES_UNIT_PEX:
  930. if (line_cfg != SERDES_UNIT_PEX)
  931. break;
  932. pex_unit = line_num >> 2;
  933. pex_line_num = line_num % 4;
  934. if (info->pex_mode[pex_unit] ==
  935. PEX_BUS_DISABLED)
  936. break;
  937. if ((info->pex_mode[pex_unit] ==
  938. PEX_BUS_MODE_X4) && pex_line_num)
  939. break;
  940. if (bus_speed) {
  941. reg_write(PEX_PHY_ACCESS_REG
  942. (pex_unit),
  943. (pex_line_num << 24) |
  944. serdes_m_phy_change->val_hi_speed);
  945. DEBUG_WR_REG(PEX_PHY_ACCESS_REG
  946. (pex_unit),
  947. (pex_line_num <<
  948. 24) |
  949. serdes_m_phy_change->val_hi_speed);
  950. } else {
  951. reg_write(PEX_PHY_ACCESS_REG
  952. (pex_unit),
  953. (pex_line_num << 24) |
  954. serdes_m_phy_change->val_low_speed);
  955. DEBUG_WR_REG(PEX_PHY_ACCESS_REG
  956. (pex_unit),
  957. (pex_line_num <<
  958. 24) |
  959. serdes_m_phy_change->val_low_speed);
  960. }
  961. break;
  962. case SERDES_UNIT_SATA:
  963. if (line_cfg != SERDES_UNIT_SATA)
  964. break;
  965. /*
  966. * Port 0 for serdes lines 4,6, and
  967. * port 1 for serdes lines 5
  968. */
  969. sata_port = line_num & 1;
  970. if (bus_speed) {
  971. reg_write(SATA_BASE_REG
  972. (sata_port) |
  973. serdes_m_phy_change->reg_hi_speed,
  974. serdes_m_phy_change->val_hi_speed);
  975. DEBUG_WR_REG(SATA_BASE_REG
  976. (sata_port) |
  977. serdes_m_phy_change->reg_hi_speed,
  978. serdes_m_phy_change->val_hi_speed);
  979. } else {
  980. reg_write(SATA_BASE_REG
  981. (sata_port) |
  982. serdes_m_phy_change->reg_low_speed,
  983. serdes_m_phy_change->val_low_speed);
  984. DEBUG_WR_REG(SATA_BASE_REG
  985. (sata_port) |
  986. serdes_m_phy_change->reg_low_speed,
  987. serdes_m_phy_change->val_low_speed);
  988. }
  989. break;
  990. case SERDES_UNIT_SGMII0:
  991. case SERDES_UNIT_SGMII1:
  992. case SERDES_UNIT_SGMII2:
  993. case SERDES_UNIT_SGMII3:
  994. if (line_cfg == serdes_cfg[line_num]
  995. [SERDES_UNIT_SGMII0])
  996. sgmii_port = 0;
  997. else if (line_cfg ==
  998. serdes_cfg[line_num]
  999. [SERDES_UNIT_SGMII1])
  1000. sgmii_port = 1;
  1001. else if (line_cfg ==
  1002. serdes_cfg[line_num]
  1003. [SERDES_UNIT_SGMII2])
  1004. sgmii_port = 2;
  1005. else if (line_cfg ==
  1006. serdes_cfg[line_num]
  1007. [SERDES_UNIT_SGMII3])
  1008. sgmii_port = 3;
  1009. else
  1010. break;
  1011. if (bus_speed) {
  1012. reg_write(MV_ETH_REGS_BASE
  1013. (sgmii_port) |
  1014. serdes_m_phy_change->reg_hi_speed,
  1015. serdes_m_phy_change->val_hi_speed);
  1016. DEBUG_WR_REG(MV_ETH_REGS_BASE
  1017. (sgmii_port) |
  1018. serdes_m_phy_change->reg_hi_speed,
  1019. serdes_m_phy_change->val_hi_speed);
  1020. } else {
  1021. reg_write(MV_ETH_REGS_BASE
  1022. (sgmii_port) |
  1023. serdes_m_phy_change->reg_low_speed,
  1024. serdes_m_phy_change->val_low_speed);
  1025. DEBUG_WR_REG(MV_ETH_REGS_BASE
  1026. (sgmii_port) |
  1027. serdes_m_phy_change->reg_low_speed,
  1028. serdes_m_phy_change->val_low_speed);
  1029. }
  1030. break;
  1031. case SERDES_UNIT_QSGMII:
  1032. if (line_cfg != SERDES_UNIT_QSGMII)
  1033. break;
  1034. if (bus_speed) {
  1035. reg_write
  1036. (serdes_m_phy_change->reg_hi_speed,
  1037. serdes_m_phy_change->val_hi_speed);
  1038. DEBUG_WR_REG
  1039. (serdes_m_phy_change->reg_hi_speed,
  1040. serdes_m_phy_change->val_hi_speed);
  1041. } else {
  1042. reg_write
  1043. (serdes_m_phy_change->reg_low_speed,
  1044. serdes_m_phy_change->val_low_speed);
  1045. DEBUG_WR_REG
  1046. (serdes_m_phy_change->reg_low_speed,
  1047. serdes_m_phy_change->val_low_speed);
  1048. }
  1049. break;
  1050. default:
  1051. break;
  1052. }
  1053. serdes_m_phy_change++;
  1054. }
  1055. }
  1056. }
  1057. /* Step 16 [PEX-Only] Training Enable */
  1058. DEBUG_INIT_FULL_S("Steps 16: [PEX-Only] Training Enable");
  1059. tmp = reg_read(SOC_CTRL_REG);
  1060. DEBUG_RD_REG(SOC_CTRL_REG, tmp);
  1061. tmp &= ~(0x0F);
  1062. for (pex_unit = 0; pex_unit < pex_max_unit_get(); pex_unit++) {
  1063. reg_write(PEX_CAUSE_REG(pex_unit), 0);
  1064. DEBUG_WR_REG(PEX_CAUSE_REG(pex_unit), 0);
  1065. if (info->pex_mode[pex_unit] != PEX_BUS_DISABLED)
  1066. tmp |= (0x1 << pex_unit);
  1067. }
  1068. reg_write(SOC_CTRL_REG, tmp);
  1069. DEBUG_WR_REG(SOC_CTRL_REG, tmp);
  1070. /* Step 17: Speed change to target speed and width */
  1071. {
  1072. u32 tmp_reg, tmp_pex_reg;
  1073. u32 addr;
  1074. u32 first_busno, next_busno;
  1075. u32 max_link_width = 0;
  1076. u32 neg_link_width = 0;
  1077. pex_if_num = pex_max_if_get();
  1078. mdelay(150);
  1079. DEBUG_INIT_FULL_C("step 17: max_if= 0x", pex_if_num, 1);
  1080. next_busno = 0;
  1081. for (pex_if = 0; pex_if < pex_if_num; pex_if++) {
  1082. line_num = (pex_if <= 8) ? pex_if : 12;
  1083. line_cfg = get_line_cfg(line_num, info);
  1084. if (line_cfg != serdes_cfg[line_num][SERDES_UNIT_PEX])
  1085. continue;
  1086. pex_unit = (pex_if < 9) ? (pex_if >> 2) : 3;
  1087. DEBUG_INIT_FULL_S("step 17: PEX");
  1088. DEBUG_INIT_FULL_D(pex_if, 1);
  1089. DEBUG_INIT_FULL_C(" pex_unit= ", pex_unit, 1);
  1090. if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) {
  1091. DEBUG_INIT_FULL_C("PEX disabled interface ",
  1092. pex_if, 1);
  1093. if (pex_if < 8)
  1094. pex_if += 3;
  1095. continue;
  1096. }
  1097. first_busno = next_busno;
  1098. if ((info->pex_type == MV_PEX_END_POINT) &&
  1099. (0 == pex_if)) {
  1100. if ((pex_if < 8) && (info->pex_mode[pex_unit] ==
  1101. PEX_BUS_MODE_X4))
  1102. pex_if += 3;
  1103. continue;
  1104. }
  1105. tmp = reg_read(PEX_DBG_STATUS_REG(pex_if));
  1106. DEBUG_RD_REG(PEX_DBG_STATUS_REG(pex_if), tmp);
  1107. if ((tmp & 0x7f) == 0x7e) {
  1108. next_busno++;
  1109. tmp = reg_read(PEX_LINK_CAPABILITIES_REG(pex_if));
  1110. max_link_width = tmp;
  1111. DEBUG_RD_REG((PEX_LINK_CAPABILITIES_REG
  1112. (pex_if)), tmp);
  1113. max_link_width = ((max_link_width >> 4) & 0x3F);
  1114. neg_link_width =
  1115. reg_read(PEX_LINK_CTRL_STATUS_REG(pex_if));
  1116. DEBUG_RD_REG((PEX_LINK_CTRL_STATUS_REG(pex_if)),
  1117. neg_link_width);
  1118. neg_link_width = ((neg_link_width >> 20) & 0x3F);
  1119. if (max_link_width > neg_link_width) {
  1120. tmp &= ~(0x3F << 4);
  1121. tmp |= (neg_link_width << 4);
  1122. reg_write(PEX_LINK_CAPABILITIES_REG
  1123. (pex_if), tmp);
  1124. DEBUG_WR_REG((PEX_LINK_CAPABILITIES_REG
  1125. (pex_if)), tmp);
  1126. mdelay(1); /* wait 1ms before reading capability for speed */
  1127. DEBUG_INIT_S("PEX");
  1128. DEBUG_INIT_D(pex_if, 1);
  1129. DEBUG_INIT_C(": change width to X",
  1130. neg_link_width, 1);
  1131. }
  1132. tmp_pex_reg =
  1133. reg_read((PEX_CFG_DIRECT_ACCESS
  1134. (pex_if,
  1135. PEX_LINK_CAPABILITY_REG)));
  1136. DEBUG_RD_REG((PEX_CFG_DIRECT_ACCESS
  1137. (pex_if,
  1138. PEX_LINK_CAPABILITY_REG)),
  1139. tmp_pex_reg);
  1140. tmp_pex_reg &= (0xF);
  1141. if (tmp_pex_reg == 0x2) {
  1142. tmp_reg =
  1143. (reg_read
  1144. (PEX_CFG_DIRECT_ACCESS
  1145. (pex_if,
  1146. PEX_LINK_CTRL_STAT_REG)) &
  1147. 0xF0000) >> 16;
  1148. DEBUG_RD_REG(PEX_CFG_DIRECT_ACCESS
  1149. (pex_if,
  1150. PEX_LINK_CTRL_STAT_REG),
  1151. tmp_pex_reg);
  1152. /* check if the link established is GEN1 */
  1153. if (tmp_reg == 0x1) {
  1154. pex_local_bus_num_set(pex_if,
  1155. first_busno);
  1156. pex_local_dev_num_set(pex_if,
  1157. 1);
  1158. DEBUG_INIT_FULL_S("** Link is Gen1, check the EP capability\n");
  1159. /* link is Gen1, check the EP capability */
  1160. addr =
  1161. pex_cfg_read(pex_if,
  1162. first_busno, 0,
  1163. 0,
  1164. 0x34) & 0xFF;
  1165. DEBUG_INIT_FULL_C("pex_cfg_read: return addr=0x%x",
  1166. addr, 4);
  1167. if (addr == 0xff) {
  1168. DEBUG_INIT_FULL_C("pex_cfg_read: return 0xff -->PEX (%d): Detected No Link.",
  1169. pex_if, 1);
  1170. continue;
  1171. }
  1172. while ((pex_cfg_read
  1173. (pex_if, first_busno, 0,
  1174. 0,
  1175. addr) & 0xFF) !=
  1176. 0x10) {
  1177. addr =
  1178. (pex_cfg_read
  1179. (pex_if,
  1180. first_busno, 0, 0,
  1181. addr) & 0xFF00) >>
  1182. 8;
  1183. }
  1184. if ((pex_cfg_read
  1185. (pex_if, first_busno, 0, 0,
  1186. addr + 0xC) & 0xF) >=
  1187. 0x2) {
  1188. tmp =
  1189. reg_read
  1190. (PEX_LINK_CTRL_STATUS2_REG
  1191. (pex_if));
  1192. DEBUG_RD_REG
  1193. (PEX_LINK_CTRL_STATUS2_REG
  1194. (pex_if), tmp);
  1195. tmp &= ~(0x1 | 1 << 1);
  1196. tmp |= (1 << 1);
  1197. reg_write
  1198. (PEX_LINK_CTRL_STATUS2_REG
  1199. (pex_if), tmp);
  1200. DEBUG_WR_REG
  1201. (PEX_LINK_CTRL_STATUS2_REG
  1202. (pex_if), tmp);
  1203. tmp =
  1204. reg_read
  1205. (PEX_CTRL_REG
  1206. (pex_if));
  1207. DEBUG_RD_REG
  1208. (PEX_CTRL_REG
  1209. (pex_if), tmp);
  1210. tmp |= (1 << 10);
  1211. reg_write(PEX_CTRL_REG
  1212. (pex_if),
  1213. tmp);
  1214. DEBUG_WR_REG
  1215. (PEX_CTRL_REG
  1216. (pex_if), tmp);
  1217. mdelay(10); /* We need to wait 10ms before reading the PEX_DBG_STATUS_REG in order not to read the status of the former state */
  1218. DEBUG_INIT_FULL_S
  1219. ("Gen2 client!\n");
  1220. } else {
  1221. DEBUG_INIT_FULL_S
  1222. ("GEN1 client!\n");
  1223. }
  1224. }
  1225. }
  1226. } else {
  1227. DEBUG_INIT_FULL_S("PEX");
  1228. DEBUG_INIT_FULL_D(pex_if, 1);
  1229. DEBUG_INIT_FULL_S(" : Detected No Link. Status Reg(0x");
  1230. DEBUG_INIT_FULL_D(PEX_DBG_STATUS_REG(pex_if),
  1231. 8);
  1232. DEBUG_INIT_FULL_C(") = 0x", tmp, 8);
  1233. }
  1234. if ((pex_if < 8) &&
  1235. (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4))
  1236. pex_if += 3;
  1237. }
  1238. }
  1239. /* Step 18: update pex DEVICE ID */
  1240. {
  1241. u32 devId;
  1242. pex_if_num = pex_max_if_get();
  1243. ctrl_mode = ctrl_model_get();
  1244. for (pex_if = 0; pex_if < pex_if_num; pex_if++) {
  1245. pex_unit = (pex_if < 9) ? (pex_if >> 2) : 3;
  1246. if (info->pex_mode[pex_unit] == PEX_BUS_DISABLED) {
  1247. if ((pex_if < 8) &&
  1248. (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4))
  1249. pex_if += 3;
  1250. continue;
  1251. }
  1252. devId = reg_read(PEX_CFG_DIRECT_ACCESS(
  1253. pex_if, PEX_DEVICE_AND_VENDOR_ID));
  1254. devId &= 0xFFFF;
  1255. devId |= ((ctrl_mode << 16) & 0xffff0000);
  1256. DEBUG_INIT_FULL_S("Update Device ID PEX");
  1257. DEBUG_INIT_FULL_D(pex_if, 1);
  1258. DEBUG_INIT_FULL_D(devId, 8);
  1259. DEBUG_INIT_FULL_S("\n");
  1260. reg_write(PEX_CFG_DIRECT_ACCESS
  1261. (pex_if, PEX_DEVICE_AND_VENDOR_ID), devId);
  1262. if ((pex_if < 8) &&
  1263. (info->pex_mode[pex_unit] == PEX_BUS_MODE_X4))
  1264. pex_if += 3;
  1265. }
  1266. DEBUG_INIT_FULL_S("Update PEX Device ID 0x");
  1267. DEBUG_INIT_FULL_D(ctrl_mode, 4);
  1268. DEBUG_INIT_FULL_S("0\n");
  1269. }
  1270. tmp = reg_read(PEX_DBG_STATUS_REG(0));
  1271. DEBUG_RD_REG(PEX_DBG_STATUS_REG(0), tmp);
  1272. DEBUG_INIT_S(ENDED_OK);
  1273. return MV_OK;
  1274. }
  1275. /* PEX configuration space read write */
  1276. /*
  1277. * pex_cfg_read - Read from configuration space
  1278. *
  1279. * DESCRIPTION:
  1280. * This function performs a 32 bit read from PEX configuration space.
  1281. * It supports both type 0 and type 1 of Configuration Transactions
  1282. * (local and over bridge). In order to read from local bus segment, use
  1283. * bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
  1284. * will result configuration transaction of type 1 (over bridge).
  1285. *
  1286. * INPUT:
  1287. * pex_if - PEX interface number.
  1288. * bus - PEX segment bus number.
  1289. * dev - PEX device number.
  1290. * func - Function number.
  1291. * offss - Register offset.
  1292. *
  1293. * OUTPUT:
  1294. * None.
  1295. *
  1296. * RETURN:
  1297. * 32bit register data, 0xffffffff on error
  1298. *
  1299. */
  1300. u32 pex_cfg_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 offs)
  1301. {
  1302. u32 pex_data = 0;
  1303. u32 local_dev, local_bus;
  1304. u32 val;
  1305. if (pex_if >= MV_PEX_MAX_IF)
  1306. return 0xFFFFFFFF;
  1307. if (dev >= MAX_PEX_DEVICES) {
  1308. DEBUG_INIT_C("pex_cfg_read: ERR. device number illigal ", dev,
  1309. 1);
  1310. return 0xFFFFFFFF;
  1311. }
  1312. if (func >= MAX_PEX_FUNCS) {
  1313. DEBUG_INIT_C("pex_cfg_read: ERR. function num illigal ", func,
  1314. 1);
  1315. return 0xFFFFFFFF;
  1316. }
  1317. if (bus >= MAX_PEX_BUSSES) {
  1318. DEBUG_INIT_C("pex_cfg_read: ERR. bus number illigal ", bus, 1);
  1319. return MV_ERROR;
  1320. }
  1321. val = reg_read(PEX_STATUS_REG(pex_if));
  1322. local_dev =
  1323. ((val & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS);
  1324. local_bus =
  1325. ((val & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS);
  1326. /* Speed up the process. In case on no link, return MV_ERROR */
  1327. if ((dev != local_dev) || (bus != local_bus)) {
  1328. pex_data = reg_read(PEX_STATUS_REG(pex_if));
  1329. if ((pex_data & PXSR_DL_DOWN))
  1330. return MV_ERROR;
  1331. }
  1332. /*
  1333. * In PCI Express we have only one device number
  1334. * and this number is the first number we encounter else that the
  1335. * local_dev spec pex define return on config read/write on any device
  1336. */
  1337. if (bus == local_bus) {
  1338. if (local_dev == 0) {
  1339. /*
  1340. * If local dev is 0 then the first number we encounter
  1341. * after 0 is 1
  1342. */
  1343. if ((dev != 1) && (dev != local_dev))
  1344. return MV_ERROR;
  1345. } else {
  1346. /*
  1347. * If local dev is not 0 then the first number we
  1348. * encounter is 0
  1349. */
  1350. if ((dev != 0) && (dev != local_dev))
  1351. return MV_ERROR;
  1352. }
  1353. }
  1354. /* Creating PEX address to be passed */
  1355. pex_data = (bus << PXCAR_BUS_NUM_OFFS);
  1356. pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS);
  1357. pex_data |= (func << PXCAR_FUNC_NUM_OFFS);
  1358. pex_data |= (offs & PXCAR_REG_NUM_MASK); /* lgacy register space */
  1359. /* extended register space */
  1360. pex_data |= (((offs & PXCAR_REAL_EXT_REG_NUM_MASK) >>
  1361. PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
  1362. pex_data |= PXCAR_CONFIG_EN;
  1363. /* Write the address to the PEX configuration address register */
  1364. reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data);
  1365. /*
  1366. * In order to let the PEX controller absorbed the address of the read
  1367. * transaction we perform a validity check that the address was written
  1368. */
  1369. if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if)))
  1370. return MV_ERROR;
  1371. /* cleaning Master Abort */
  1372. reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND),
  1373. PXSAC_MABORT);
  1374. /* Read the Data returned in the PEX Data register */
  1375. pex_data = reg_read(PEX_CFG_DATA_REG(pex_if));
  1376. DEBUG_INIT_FULL_C(" --> ", pex_data, 4);
  1377. return pex_data;
  1378. }
  1379. /*
  1380. * pex_local_bus_num_set - Set PEX interface local bus number.
  1381. *
  1382. * DESCRIPTION:
  1383. * This function sets given PEX interface its local bus number.
  1384. * Note: In case the PEX interface is PEX-X, the information is read-only.
  1385. *
  1386. * INPUT:
  1387. * pex_if - PEX interface number.
  1388. * bus_num - Bus number.
  1389. *
  1390. * OUTPUT:
  1391. * None.
  1392. *
  1393. * RETURN:
  1394. * MV_NOT_ALLOWED in case PEX interface is PEX-X.
  1395. * MV_BAD_PARAM on bad parameters ,
  1396. * otherwise MV_OK
  1397. *
  1398. */
  1399. int pex_local_bus_num_set(u32 pex_if, u32 bus_num)
  1400. {
  1401. u32 val;
  1402. if (bus_num >= MAX_PEX_BUSSES) {
  1403. DEBUG_INIT_C("pex_local_bus_num_set: ERR. bus number illigal %d\n",
  1404. bus_num, 4);
  1405. return MV_ERROR;
  1406. }
  1407. val = reg_read(PEX_STATUS_REG(pex_if));
  1408. val &= ~PXSR_PEX_BUS_NUM_MASK;
  1409. val |= (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
  1410. reg_write(PEX_STATUS_REG(pex_if), val);
  1411. return MV_OK;
  1412. }
  1413. /*
  1414. * pex_local_dev_num_set - Set PEX interface local device number.
  1415. *
  1416. * DESCRIPTION:
  1417. * This function sets given PEX interface its local device number.
  1418. * Note: In case the PEX interface is PEX-X, the information is read-only.
  1419. *
  1420. * INPUT:
  1421. * pex_if - PEX interface number.
  1422. * dev_num - Device number.
  1423. *
  1424. * OUTPUT:
  1425. * None.
  1426. *
  1427. * RETURN:
  1428. * MV_NOT_ALLOWED in case PEX interface is PEX-X.
  1429. * MV_BAD_PARAM on bad parameters ,
  1430. * otherwise MV_OK
  1431. *
  1432. */
  1433. int pex_local_dev_num_set(u32 pex_if, u32 dev_num)
  1434. {
  1435. u32 val;
  1436. if (pex_if >= MV_PEX_MAX_IF)
  1437. return MV_BAD_PARAM;
  1438. val = reg_read(PEX_STATUS_REG(pex_if));
  1439. val &= ~PXSR_PEX_DEV_NUM_MASK;
  1440. val |= (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
  1441. reg_write(PEX_STATUS_REG(pex_if), val);
  1442. return MV_OK;
  1443. }