cvmx-qlm.c 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2020 Marvell International Ltd.
  4. *
  5. * Helper utilities for qlm.
  6. */
  7. #include <log.h>
  8. #include <time.h>
  9. #include <asm/global_data.h>
  10. #include <linux/delay.h>
  11. #include <mach/cvmx-regs.h>
  12. #include <mach/octeon-model.h>
  13. #include <mach/cvmx-fuse.h>
  14. #include <mach/octeon-feature.h>
  15. #include <mach/cvmx-qlm.h>
  16. #include <mach/octeon_qlm.h>
  17. #include <mach/cvmx-pcie.h>
  18. #include <mach/cvmx-helper.h>
  19. #include <mach/cvmx-helper-util.h>
  20. #include <mach/cvmx-bgxx-defs.h>
  21. #include <mach/cvmx-ciu-defs.h>
  22. #include <mach/cvmx-gmxx-defs.h>
  23. #include <mach/cvmx-gserx-defs.h>
  24. #include <mach/cvmx-mio-defs.h>
  25. #include <mach/cvmx-pciercx-defs.h>
  26. #include <mach/cvmx-pemx-defs.h>
  27. #include <mach/cvmx-pexp-defs.h>
  28. #include <mach/cvmx-rst-defs.h>
  29. #include <mach/cvmx-sata-defs.h>
  30. #include <mach/cvmx-sli-defs.h>
  31. #include <mach/cvmx-sriomaintx-defs.h>
  32. #include <mach/cvmx-sriox-defs.h>
  33. #include <mach/cvmx-helper.h>
  34. #include <mach/cvmx-helper-jtag.h>
  35. DECLARE_GLOBAL_DATA_PTR;
  36. /*
  37. * Their is a copy of this in bootloader qlm configuration, make sure
  38. * to update both the places till i figure out
  39. */
  40. #define R_25G_REFCLK100 0x0
  41. #define R_5G_REFCLK100 0x1
  42. #define R_8G_REFCLK100 0x2
  43. #define R_125G_REFCLK15625_KX 0x3
  44. #define R_3125G_REFCLK15625_XAUI 0x4
  45. #define R_103125G_REFCLK15625_KR 0x5
  46. #define R_125G_REFCLK15625_SGMII 0x6
  47. #define R_5G_REFCLK15625_QSGMII 0x7
  48. #define R_625G_REFCLK15625_RXAUI 0x8
  49. #define R_25G_REFCLK125 0x9
  50. #define R_5G_REFCLK125 0xa
  51. #define R_8G_REFCLK125 0xb
  52. static const int REF_100MHZ = 100000000;
  53. static const int REF_125MHZ = 125000000;
  54. static const int REF_156MHZ = 156250000;
  55. static qlm_jtag_uint32_t *__cvmx_qlm_jtag_xor_ref;
  56. /**
  57. * Return the number of QLMs supported by the chip
  58. *
  59. * Return: Number of QLMs
  60. */
  61. int cvmx_qlm_get_num(void)
  62. {
  63. if (OCTEON_IS_MODEL(OCTEON_CN68XX))
  64. return 5;
  65. else if (OCTEON_IS_MODEL(OCTEON_CN66XX))
  66. return 3;
  67. else if (OCTEON_IS_MODEL(OCTEON_CN63XX))
  68. return 3;
  69. else if (OCTEON_IS_MODEL(OCTEON_CN61XX))
  70. return 3;
  71. else if (OCTEON_IS_MODEL(OCTEON_CNF71XX))
  72. return 2;
  73. else if (OCTEON_IS_MODEL(OCTEON_CN78XX))
  74. return 8;
  75. else if (OCTEON_IS_MODEL(OCTEON_CN73XX))
  76. return 7;
  77. else if (OCTEON_IS_MODEL(OCTEON_CNF75XX))
  78. return 9;
  79. return 0;
  80. }
  81. /**
  82. * Return the qlm number based on the interface
  83. *
  84. * @param xiface interface to look up
  85. *
  86. * Return: the qlm number based on the xiface
  87. */
  88. int cvmx_qlm_interface(int xiface)
  89. {
  90. struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
  91. if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
  92. return (xi.interface == 0) ? 2 : 0;
  93. } else if (OCTEON_IS_MODEL(OCTEON_CN63XX) || OCTEON_IS_MODEL(OCTEON_CN66XX)) {
  94. return 2 - xi.interface;
  95. } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
  96. if (xi.interface == 0)
  97. return 0;
  98. debug("Warning: %s: Invalid interface %d\n",
  99. __func__, xi.interface);
  100. } else if (octeon_has_feature(OCTEON_FEATURE_BGX)) {
  101. debug("Warning: not supported\n");
  102. return -1;
  103. }
  104. /* Must be cn68XX */
  105. switch (xi.interface) {
  106. case 1:
  107. return 0;
  108. default:
  109. return xi.interface;
  110. }
  111. return -1;
  112. }
  113. /**
  114. * Return the qlm number based for a port in the interface
  115. *
  116. * @param xiface interface to look up
  117. * @param index index in an interface
  118. *
  119. * Return: the qlm number based on the xiface
  120. */
  121. int cvmx_qlm_lmac(int xiface, int index)
  122. {
  123. struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
  124. if (OCTEON_IS_MODEL(OCTEON_CN78XX)) {
  125. cvmx_bgxx_cmr_global_config_t gconfig;
  126. cvmx_gserx_phy_ctl_t phy_ctl;
  127. cvmx_gserx_cfg_t gserx_cfg;
  128. int qlm;
  129. if (xi.interface < 6) {
  130. if (xi.interface < 2) {
  131. gconfig.u64 =
  132. csr_rd_node(xi.node,
  133. CVMX_BGXX_CMR_GLOBAL_CONFIG(xi.interface));
  134. if (gconfig.s.pmux_sds_sel)
  135. qlm = xi.interface + 2; /* QLM 2 or 3 */
  136. else
  137. qlm = xi.interface; /* QLM 0 or 1 */
  138. } else {
  139. qlm = xi.interface + 2; /* QLM 4-7 */
  140. }
  141. /* make sure the QLM is powered up and out of reset */
  142. phy_ctl.u64 = csr_rd_node(xi.node, CVMX_GSERX_PHY_CTL(qlm));
  143. if (phy_ctl.s.phy_pd || phy_ctl.s.phy_reset)
  144. return -1;
  145. gserx_cfg.u64 = csr_rd_node(xi.node, CVMX_GSERX_CFG(qlm));
  146. if (gserx_cfg.s.bgx)
  147. return qlm;
  148. else
  149. return -1;
  150. } else if (xi.interface <= 7) { /* ILK */
  151. int qlm;
  152. for (qlm = 4; qlm < 8; qlm++) {
  153. /* Make sure the QLM is powered and out of reset */
  154. phy_ctl.u64 = csr_rd_node(xi.node, CVMX_GSERX_PHY_CTL(qlm));
  155. if (phy_ctl.s.phy_pd || phy_ctl.s.phy_reset)
  156. continue;
  157. /* Make sure the QLM is in ILK mode */
  158. gserx_cfg.u64 = csr_rd_node(xi.node, CVMX_GSERX_CFG(qlm));
  159. if (gserx_cfg.s.ila)
  160. return qlm;
  161. }
  162. }
  163. return -1;
  164. } else if (OCTEON_IS_MODEL(OCTEON_CN73XX)) {
  165. cvmx_gserx_phy_ctl_t phy_ctl;
  166. cvmx_gserx_cfg_t gserx_cfg;
  167. int qlm;
  168. /* (interface)0->QLM2, 1->QLM3, 2->DLM5/3->DLM6 */
  169. if (xi.interface < 2) {
  170. qlm = xi.interface + 2; /* (0,1)->ret(2,3) */
  171. phy_ctl.u64 = csr_rd(CVMX_GSERX_PHY_CTL(qlm));
  172. if (phy_ctl.s.phy_pd || phy_ctl.s.phy_reset)
  173. return -1;
  174. gserx_cfg.u64 = csr_rd(CVMX_GSERX_CFG(qlm));
  175. if (gserx_cfg.s.bgx)
  176. return qlm;
  177. else
  178. return -1;
  179. } else if (xi.interface == 2) {
  180. cvmx_gserx_cfg_t g1, g2;
  181. g1.u64 = csr_rd(CVMX_GSERX_CFG(5));
  182. g2.u64 = csr_rd(CVMX_GSERX_CFG(6));
  183. /* Check if both QLM5 & QLM6 are BGX2 */
  184. if (g2.s.bgx) {
  185. if (g1.s.bgx) {
  186. cvmx_gserx_phy_ctl_t phy_ctl1;
  187. phy_ctl.u64 = csr_rd(CVMX_GSERX_PHY_CTL(5));
  188. phy_ctl1.u64 = csr_rd(CVMX_GSERX_PHY_CTL(6));
  189. if ((phy_ctl.s.phy_pd || phy_ctl.s.phy_reset) &&
  190. (phy_ctl1.s.phy_pd || phy_ctl1.s.phy_reset))
  191. return -1;
  192. if (index >= 2)
  193. return 6;
  194. return 5;
  195. } else { /* QLM6 is BGX2 */
  196. phy_ctl.u64 = csr_rd(CVMX_GSERX_PHY_CTL(6));
  197. if (phy_ctl.s.phy_pd || phy_ctl.s.phy_reset)
  198. return -1;
  199. return 6;
  200. }
  201. } else if (g1.s.bgx) {
  202. phy_ctl.u64 = csr_rd(CVMX_GSERX_PHY_CTL(5));
  203. if (phy_ctl.s.phy_pd || phy_ctl.s.phy_reset)
  204. return -1;
  205. return 5;
  206. }
  207. }
  208. return -1;
  209. } else if (OCTEON_IS_MODEL(OCTEON_CNF75XX)) {
  210. cvmx_gserx_phy_ctl_t phy_ctl;
  211. cvmx_gserx_cfg_t gserx_cfg;
  212. int qlm;
  213. if (xi.interface == 0) {
  214. cvmx_gserx_cfg_t g1, g2;
  215. g1.u64 = csr_rd(CVMX_GSERX_CFG(4));
  216. g2.u64 = csr_rd(CVMX_GSERX_CFG(5));
  217. /* Check if both QLM4 & QLM5 are BGX0 */
  218. if (g2.s.bgx) {
  219. if (g1.s.bgx) {
  220. cvmx_gserx_phy_ctl_t phy_ctl1;
  221. phy_ctl.u64 = csr_rd(CVMX_GSERX_PHY_CTL(4));
  222. phy_ctl1.u64 = csr_rd(CVMX_GSERX_PHY_CTL(5));
  223. if ((phy_ctl.s.phy_pd || phy_ctl.s.phy_reset) &&
  224. (phy_ctl1.s.phy_pd || phy_ctl1.s.phy_reset))
  225. return -1;
  226. if (index >= 2)
  227. return 5;
  228. return 4;
  229. }
  230. /* QLM5 is BGX0 */
  231. phy_ctl.u64 = csr_rd(CVMX_GSERX_PHY_CTL(5));
  232. if (phy_ctl.s.phy_pd || phy_ctl.s.phy_reset)
  233. return -1;
  234. return 5;
  235. } else if (g1.s.bgx) {
  236. phy_ctl.u64 = csr_rd(CVMX_GSERX_PHY_CTL(4));
  237. if (phy_ctl.s.phy_pd || phy_ctl.s.phy_reset)
  238. return -1;
  239. return 4;
  240. }
  241. } else if (xi.interface < 2) {
  242. qlm = (xi.interface == 1) ? 2 : 3;
  243. gserx_cfg.u64 = csr_rd(CVMX_GSERX_CFG(qlm));
  244. if (gserx_cfg.s.srio)
  245. return qlm;
  246. }
  247. return -1;
  248. }
  249. return -1;
  250. }
  251. /**
  252. * Return if only DLM5/DLM6/DLM5+DLM6 is used by BGX
  253. *
  254. * @param BGX BGX to search for.
  255. *
  256. * Return: muxes used 0 = DLM5+DLM6, 1 = DLM5, 2 = DLM6.
  257. */
  258. int cvmx_qlm_mux_interface(int bgx)
  259. {
  260. int mux = 0;
  261. cvmx_gserx_cfg_t gser1, gser2;
  262. int qlm1, qlm2;
  263. if (OCTEON_IS_MODEL(OCTEON_CN73XX) && bgx != 2)
  264. return -1;
  265. else if (OCTEON_IS_MODEL(OCTEON_CNF75XX) && bgx != 0)
  266. return -1;
  267. if (OCTEON_IS_MODEL(OCTEON_CN73XX)) {
  268. qlm1 = 5;
  269. qlm2 = 6;
  270. } else if (OCTEON_IS_MODEL(OCTEON_CNF75XX)) {
  271. qlm1 = 4;
  272. qlm2 = 5;
  273. } else {
  274. return -1;
  275. }
  276. gser1.u64 = csr_rd(CVMX_GSERX_CFG(qlm1));
  277. gser2.u64 = csr_rd(CVMX_GSERX_CFG(qlm2));
  278. if (gser1.s.bgx && gser2.s.bgx)
  279. mux = 0;
  280. else if (gser1.s.bgx)
  281. mux = 1; // BGX2 is using DLM5 only
  282. else if (gser2.s.bgx)
  283. mux = 2; // BGX2 is using DLM6 only
  284. return mux;
  285. }
  286. /**
  287. * Return number of lanes for a given qlm
  288. *
  289. * @param qlm QLM to examine
  290. *
  291. * Return: Number of lanes
  292. */
  293. int cvmx_qlm_get_lanes(int qlm)
  294. {
  295. if (OCTEON_IS_MODEL(OCTEON_CN61XX) && qlm == 1)
  296. return 2;
  297. else if (OCTEON_IS_MODEL(OCTEON_CNF71XX))
  298. return 2;
  299. else if (OCTEON_IS_MODEL(OCTEON_CN73XX))
  300. return (qlm < 4) ? 4 /*QLM0,1,2,3*/ : 2 /*DLM4,5,6*/;
  301. else if (OCTEON_IS_MODEL(OCTEON_CNF75XX))
  302. return (qlm == 2 || qlm == 3) ? 4 /*QLM2,3*/ : 2 /*DLM0,1,4,5*/;
  303. return 4;
  304. }
  305. /**
  306. * Get the QLM JTAG fields based on Octeon model on the supported chips.
  307. *
  308. * Return: qlm_jtag_field_t structure
  309. */
  310. const __cvmx_qlm_jtag_field_t *cvmx_qlm_jtag_get_field(void)
  311. {
  312. /* Figure out which JTAG chain description we're using */
  313. if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
  314. return __cvmx_qlm_jtag_field_cn68xx;
  315. } else if (OCTEON_IS_MODEL(OCTEON_CN66XX) || OCTEON_IS_MODEL(OCTEON_CN61XX) ||
  316. OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
  317. return __cvmx_qlm_jtag_field_cn66xx;
  318. } else if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
  319. return __cvmx_qlm_jtag_field_cn63xx;
  320. }
  321. return NULL;
  322. }
  323. /**
  324. * Get the QLM JTAG length by going through qlm_jtag_field for each
  325. * Octeon model that is supported
  326. *
  327. * Return: return the length.
  328. */
  329. int cvmx_qlm_jtag_get_length(void)
  330. {
  331. const __cvmx_qlm_jtag_field_t *qlm_ptr = cvmx_qlm_jtag_get_field();
  332. int length = 0;
  333. /* Figure out how many bits are in the JTAG chain */
  334. while (qlm_ptr && qlm_ptr->name) {
  335. if (qlm_ptr->stop_bit > length)
  336. length = qlm_ptr->stop_bit + 1;
  337. qlm_ptr++;
  338. }
  339. return length;
  340. }
  341. /**
  342. * Initialize the QLM layer
  343. */
  344. void cvmx_qlm_init(void)
  345. {
  346. if (OCTEON_IS_OCTEON3())
  347. return;
  348. /* ToDo: No support for non-Octeon 3 yet */
  349. printf("Please add support for unsupported Octeon SoC\n");
  350. }
  351. /**
  352. * Lookup the bit information for a JTAG field name
  353. *
  354. * @param name Name to lookup
  355. *
  356. * Return: Field info, or NULL on failure
  357. */
  358. static const __cvmx_qlm_jtag_field_t *__cvmx_qlm_lookup_field(const char *name)
  359. {
  360. const __cvmx_qlm_jtag_field_t *ptr = cvmx_qlm_jtag_get_field();
  361. while (ptr->name) {
  362. if (strcmp(name, ptr->name) == 0)
  363. return ptr;
  364. ptr++;
  365. }
  366. debug("%s: Illegal field name %s\n", __func__, name);
  367. return NULL;
  368. }
  369. /**
  370. * Get a field in a QLM JTAG chain
  371. *
  372. * @param qlm QLM to get
  373. * @param lane Lane in QLM to get
  374. * @param name String name of field
  375. *
  376. * Return: JTAG field value
  377. */
  378. uint64_t cvmx_qlm_jtag_get(int qlm, int lane, const char *name)
  379. {
  380. const __cvmx_qlm_jtag_field_t *field = __cvmx_qlm_lookup_field(name);
  381. int qlm_jtag_length = cvmx_qlm_jtag_get_length();
  382. int num_lanes = cvmx_qlm_get_lanes(qlm);
  383. if (!field)
  384. return 0;
  385. /* Capture the current settings */
  386. cvmx_helper_qlm_jtag_capture(qlm);
  387. /*
  388. * Shift past lanes we don't care about. CN6XXX/7XXX shifts lane 0 first,
  389. * CN3XXX/5XXX shifts lane 3 first
  390. */
  391. /* Shift to the start of the field */
  392. cvmx_helper_qlm_jtag_shift_zeros(qlm,
  393. qlm_jtag_length * (num_lanes - 1 - lane));
  394. cvmx_helper_qlm_jtag_shift_zeros(qlm, field->start_bit);
  395. /* Shift out the value and return it */
  396. return cvmx_helper_qlm_jtag_shift(qlm, field->stop_bit - field->start_bit + 1, 0);
  397. }
  398. /**
  399. * Set a field in a QLM JTAG chain
  400. *
  401. * @param qlm QLM to set
  402. * @param lane Lane in QLM to set, or -1 for all lanes
  403. * @param name String name of field
  404. * @param value Value of the field
  405. */
  406. void cvmx_qlm_jtag_set(int qlm, int lane, const char *name, uint64_t value)
  407. {
  408. int i, l;
  409. u32 shift_values[CVMX_QLM_JTAG_UINT32];
  410. int num_lanes = cvmx_qlm_get_lanes(qlm);
  411. const __cvmx_qlm_jtag_field_t *field = __cvmx_qlm_lookup_field(name);
  412. int qlm_jtag_length = cvmx_qlm_jtag_get_length();
  413. int total_length = qlm_jtag_length * num_lanes;
  414. int bits = 0;
  415. if (!field)
  416. return;
  417. /* Get the current state */
  418. cvmx_helper_qlm_jtag_capture(qlm);
  419. for (i = 0; i < CVMX_QLM_JTAG_UINT32; i++)
  420. shift_values[i] = cvmx_helper_qlm_jtag_shift(qlm, 32, 0);
  421. /* Put new data in our local array */
  422. for (l = 0; l < num_lanes; l++) {
  423. u64 new_value = value;
  424. int bits;
  425. int adj_lanes;
  426. if (l != lane && lane != -1)
  427. continue;
  428. adj_lanes = (num_lanes - 1 - l) * qlm_jtag_length;
  429. for (bits = field->start_bit + adj_lanes; bits <= field->stop_bit + adj_lanes;
  430. bits++) {
  431. if (new_value & 1)
  432. shift_values[bits / 32] |= 1 << (bits & 31);
  433. else
  434. shift_values[bits / 32] &= ~(1 << (bits & 31));
  435. new_value >>= 1;
  436. }
  437. }
  438. /* Shift out data and xor with reference */
  439. while (bits < total_length) {
  440. u32 shift = shift_values[bits / 32] ^ __cvmx_qlm_jtag_xor_ref[qlm][bits / 32];
  441. int width = total_length - bits;
  442. if (width > 32)
  443. width = 32;
  444. cvmx_helper_qlm_jtag_shift(qlm, width, shift);
  445. bits += 32;
  446. }
  447. /* Update the new data */
  448. cvmx_helper_qlm_jtag_update(qlm);
  449. /*
  450. * Always give the QLM 1ms to settle after every update. This may not
  451. * always be needed, but some of the options make significant
  452. * electrical changes
  453. */
  454. udelay(1000);
  455. }
  456. /**
  457. * Errata G-16094: QLM Gen2 Equalizer Default Setting Change.
  458. * CN68XX pass 1.x and CN66XX pass 1.x QLM tweak. This function tweaks the
  459. * JTAG setting for a QLMs to run better at 5 and 6.25Ghz.
  460. */
  461. void __cvmx_qlm_speed_tweak(void)
  462. {
  463. cvmx_mio_qlmx_cfg_t qlm_cfg;
  464. int num_qlms = cvmx_qlm_get_num();
  465. int qlm;
  466. /* Workaround for Errata (G-16467) */
  467. if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2_X)) {
  468. for (qlm = 0; qlm < num_qlms; qlm++) {
  469. int ir50dac;
  470. /*
  471. * This workaround only applies to QLMs running at
  472. * 6.25Ghz
  473. */
  474. if (cvmx_qlm_get_gbaud_mhz(qlm) == 6250) {
  475. #ifdef CVMX_QLM_DUMP_STATE
  476. debug("%s:%d: QLM%d: Applying workaround for Errata G-16467\n",
  477. __func__, __LINE__, qlm);
  478. cvmx_qlm_display_registers(qlm);
  479. debug("\n");
  480. #endif
  481. cvmx_qlm_jtag_set(qlm, -1, "cfg_cdr_trunc", 0);
  482. /* Hold the QLM in reset */
  483. cvmx_qlm_jtag_set(qlm, -1, "cfg_rst_n_set", 0);
  484. cvmx_qlm_jtag_set(qlm, -1, "cfg_rst_n_clr", 1);
  485. /* Forcfe TX to be idle */
  486. cvmx_qlm_jtag_set(qlm, -1, "cfg_tx_idle_clr", 0);
  487. cvmx_qlm_jtag_set(qlm, -1, "cfg_tx_idle_set", 1);
  488. if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2_0)) {
  489. ir50dac = cvmx_qlm_jtag_get(qlm, 0, "ir50dac");
  490. while (++ir50dac <= 31)
  491. cvmx_qlm_jtag_set(qlm, -1, "ir50dac", ir50dac);
  492. }
  493. cvmx_qlm_jtag_set(qlm, -1, "div4_byp", 0);
  494. cvmx_qlm_jtag_set(qlm, -1, "clkf_byp", 16);
  495. cvmx_qlm_jtag_set(qlm, -1, "serdes_pll_byp", 1);
  496. cvmx_qlm_jtag_set(qlm, -1, "spdsel_byp", 1);
  497. #ifdef CVMX_QLM_DUMP_STATE
  498. debug("%s:%d: QLM%d: Done applying workaround for Errata G-16467\n",
  499. __func__, __LINE__, qlm);
  500. cvmx_qlm_display_registers(qlm);
  501. debug("\n\n");
  502. #endif
  503. /*
  504. * The QLM will be taken out of reset later
  505. * when ILK/XAUI are initialized.
  506. */
  507. }
  508. }
  509. } else if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS1_X) ||
  510. OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_X)) {
  511. /* Loop through the QLMs */
  512. for (qlm = 0; qlm < num_qlms; qlm++) {
  513. /* Read the QLM speed */
  514. qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(qlm));
  515. /* If the QLM is at 6.25Ghz or 5Ghz then program JTAG */
  516. if (qlm_cfg.s.qlm_spd == 5 || qlm_cfg.s.qlm_spd == 12 ||
  517. qlm_cfg.s.qlm_spd == 0 || qlm_cfg.s.qlm_spd == 6 ||
  518. qlm_cfg.s.qlm_spd == 11) {
  519. cvmx_qlm_jtag_set(qlm, -1, "rx_cap_gen2", 0x1);
  520. cvmx_qlm_jtag_set(qlm, -1, "rx_eq_gen2", 0x8);
  521. }
  522. }
  523. }
  524. }
  525. /**
  526. * Errata G-16174: QLM Gen2 PCIe IDLE DAC change.
  527. * CN68XX pass 1.x, CN66XX pass 1.x and CN63XX pass 1.0-2.2 QLM tweak.
  528. * This function tweaks the JTAG setting for a QLMs for PCIe to run better.
  529. */
  530. void __cvmx_qlm_pcie_idle_dac_tweak(void)
  531. {
  532. int num_qlms = 0;
  533. int qlm;
  534. if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS1_X))
  535. num_qlms = 5;
  536. else if (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_X))
  537. num_qlms = 3;
  538. else if (OCTEON_IS_MODEL(OCTEON_CN63XX))
  539. num_qlms = 3;
  540. else
  541. return;
  542. /* Loop through the QLMs */
  543. for (qlm = 0; qlm < num_qlms; qlm++)
  544. cvmx_qlm_jtag_set(qlm, -1, "idle_dac", 0x2);
  545. }
  546. void __cvmx_qlm_pcie_cfg_rxd_set_tweak(int qlm, int lane)
  547. {
  548. if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
  549. cvmx_qlm_jtag_set(qlm, lane, "cfg_rxd_set", 0x1);
  550. }
  551. /**
  552. * Get the speed (Gbaud) of the QLM in Mhz for a given node.
  553. *
  554. * @param node node of the QLM
  555. * @param qlm QLM to examine
  556. *
  557. * Return: Speed in Mhz
  558. */
  559. int cvmx_qlm_get_gbaud_mhz_node(int node, int qlm)
  560. {
  561. cvmx_gserx_lane_mode_t lane_mode;
  562. cvmx_gserx_cfg_t cfg;
  563. if (!octeon_has_feature(OCTEON_FEATURE_MULTINODE))
  564. return 0;
  565. if (qlm >= 8)
  566. return -1; /* FIXME for OCI */
  567. /* Check if QLM is configured */
  568. cfg.u64 = csr_rd_node(node, CVMX_GSERX_CFG(qlm));
  569. if (cfg.u64 == 0)
  570. return -1;
  571. if (cfg.s.pcie) {
  572. int pem = 0;
  573. cvmx_pemx_cfg_t pemx_cfg;
  574. switch (qlm) {
  575. case 0: /* Either PEM0 x4 of PEM0 x8 */
  576. pem = 0;
  577. break;
  578. case 1: /* Either PEM0 x4 of PEM1 x4 */
  579. pemx_cfg.u64 = csr_rd_node(node, CVMX_PEMX_CFG(0));
  580. if (pemx_cfg.cn78xx.lanes8)
  581. pem = 0;
  582. else
  583. pem = 1;
  584. break;
  585. case 2: /* Either PEM2 x4 of PEM2 x8 */
  586. pem = 2;
  587. break;
  588. case 3: /* Either PEM2 x8 of PEM3 x4 or x8 */
  589. /* Can be last 4 lanes of PEM2 */
  590. pemx_cfg.u64 = csr_rd_node(node, CVMX_PEMX_CFG(2));
  591. if (pemx_cfg.cn78xx.lanes8) {
  592. pem = 2;
  593. } else {
  594. pemx_cfg.u64 = csr_rd_node(node, CVMX_PEMX_CFG(3));
  595. if (pemx_cfg.cn78xx.lanes8)
  596. pem = 3;
  597. else
  598. pem = 2;
  599. }
  600. break;
  601. case 4: /* Either PEM3 x8 of PEM3 x4 */
  602. pem = 3;
  603. break;
  604. default:
  605. debug("QLM%d: Should be in PCIe mode\n", qlm);
  606. break;
  607. }
  608. pemx_cfg.u64 = csr_rd_node(node, CVMX_PEMX_CFG(pem));
  609. switch (pemx_cfg.s.md) {
  610. case 0: /* Gen1 */
  611. return 2500;
  612. case 1: /* Gen2 */
  613. return 5000;
  614. case 2: /* Gen3 */
  615. return 8000;
  616. default:
  617. return 0;
  618. }
  619. } else {
  620. lane_mode.u64 = csr_rd_node(node, CVMX_GSERX_LANE_MODE(qlm));
  621. switch (lane_mode.s.lmode) {
  622. case R_25G_REFCLK100:
  623. return 2500;
  624. case R_5G_REFCLK100:
  625. return 5000;
  626. case R_8G_REFCLK100:
  627. return 8000;
  628. case R_125G_REFCLK15625_KX:
  629. return 1250;
  630. case R_3125G_REFCLK15625_XAUI:
  631. return 3125;
  632. case R_103125G_REFCLK15625_KR:
  633. return 10312;
  634. case R_125G_REFCLK15625_SGMII:
  635. return 1250;
  636. case R_5G_REFCLK15625_QSGMII:
  637. return 5000;
  638. case R_625G_REFCLK15625_RXAUI:
  639. return 6250;
  640. case R_25G_REFCLK125:
  641. return 2500;
  642. case R_5G_REFCLK125:
  643. return 5000;
  644. case R_8G_REFCLK125:
  645. return 8000;
  646. default:
  647. return 0;
  648. }
  649. }
  650. }
  651. /**
  652. * Get the speed (Gbaud) of the QLM in Mhz.
  653. *
  654. * @param qlm QLM to examine
  655. *
  656. * Return: Speed in Mhz
  657. */
  658. int cvmx_qlm_get_gbaud_mhz(int qlm)
  659. {
  660. if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
  661. if (qlm == 2) {
  662. cvmx_gmxx_inf_mode_t inf_mode;
  663. inf_mode.u64 = csr_rd(CVMX_GMXX_INF_MODE(0));
  664. switch (inf_mode.s.speed) {
  665. case 0:
  666. return 5000; /* 5 Gbaud */
  667. case 1:
  668. return 2500; /* 2.5 Gbaud */
  669. case 2:
  670. return 2500; /* 2.5 Gbaud */
  671. case 3:
  672. return 1250; /* 1.25 Gbaud */
  673. case 4:
  674. return 1250; /* 1.25 Gbaud */
  675. case 5:
  676. return 6250; /* 6.25 Gbaud */
  677. case 6:
  678. return 5000; /* 5 Gbaud */
  679. case 7:
  680. return 2500; /* 2.5 Gbaud */
  681. case 8:
  682. return 3125; /* 3.125 Gbaud */
  683. case 9:
  684. return 2500; /* 2.5 Gbaud */
  685. case 10:
  686. return 1250; /* 1.25 Gbaud */
  687. case 11:
  688. return 5000; /* 5 Gbaud */
  689. case 12:
  690. return 6250; /* 6.25 Gbaud */
  691. case 13:
  692. return 3750; /* 3.75 Gbaud */
  693. case 14:
  694. return 3125; /* 3.125 Gbaud */
  695. default:
  696. return 0; /* Disabled */
  697. }
  698. } else {
  699. cvmx_sriox_status_reg_t status_reg;
  700. status_reg.u64 = csr_rd(CVMX_SRIOX_STATUS_REG(qlm));
  701. if (status_reg.s.srio) {
  702. cvmx_sriomaintx_port_0_ctl2_t sriomaintx_port_0_ctl2;
  703. sriomaintx_port_0_ctl2.u32 =
  704. csr_rd(CVMX_SRIOMAINTX_PORT_0_CTL2(qlm));
  705. switch (sriomaintx_port_0_ctl2.s.sel_baud) {
  706. case 1:
  707. return 1250; /* 1.25 Gbaud */
  708. case 2:
  709. return 2500; /* 2.5 Gbaud */
  710. case 3:
  711. return 3125; /* 3.125 Gbaud */
  712. case 4:
  713. return 5000; /* 5 Gbaud */
  714. case 5:
  715. return 6250; /* 6.250 Gbaud */
  716. default:
  717. return 0; /* Disabled */
  718. }
  719. } else {
  720. cvmx_pciercx_cfg032_t pciercx_cfg032;
  721. pciercx_cfg032.u32 = csr_rd(CVMX_PCIERCX_CFG032(qlm));
  722. switch (pciercx_cfg032.s.ls) {
  723. case 1:
  724. return 2500;
  725. case 2:
  726. return 5000;
  727. case 4:
  728. return 8000;
  729. default: {
  730. cvmx_mio_rst_boot_t mio_rst_boot;
  731. mio_rst_boot.u64 = csr_rd(CVMX_MIO_RST_BOOT);
  732. if (qlm == 0 && mio_rst_boot.s.qlm0_spd == 0xf)
  733. return 0;
  734. if (qlm == 1 && mio_rst_boot.s.qlm1_spd == 0xf)
  735. return 0;
  736. /* Best guess I can make */
  737. return 5000;
  738. }
  739. }
  740. }
  741. }
  742. } else if (OCTEON_IS_OCTEON2()) {
  743. cvmx_mio_qlmx_cfg_t qlm_cfg;
  744. qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(qlm));
  745. switch (qlm_cfg.s.qlm_spd) {
  746. case 0:
  747. return 5000; /* 5 Gbaud */
  748. case 1:
  749. return 2500; /* 2.5 Gbaud */
  750. case 2:
  751. return 2500; /* 2.5 Gbaud */
  752. case 3:
  753. return 1250; /* 1.25 Gbaud */
  754. case 4:
  755. return 1250; /* 1.25 Gbaud */
  756. case 5:
  757. return 6250; /* 6.25 Gbaud */
  758. case 6:
  759. return 5000; /* 5 Gbaud */
  760. case 7:
  761. return 2500; /* 2.5 Gbaud */
  762. case 8:
  763. return 3125; /* 3.125 Gbaud */
  764. case 9:
  765. return 2500; /* 2.5 Gbaud */
  766. case 10:
  767. return 1250; /* 1.25 Gbaud */
  768. case 11:
  769. return 5000; /* 5 Gbaud */
  770. case 12:
  771. return 6250; /* 6.25 Gbaud */
  772. case 13:
  773. return 3750; /* 3.75 Gbaud */
  774. case 14:
  775. return 3125; /* 3.125 Gbaud */
  776. default:
  777. return 0; /* Disabled */
  778. }
  779. } else if (OCTEON_IS_MODEL(OCTEON_CN70XX)) {
  780. cvmx_gserx_dlmx_mpll_multiplier_t mpll_multiplier;
  781. u64 meas_refclock;
  782. u64 freq;
  783. /* Measure the reference clock */
  784. meas_refclock = cvmx_qlm_measure_clock(qlm);
  785. /* Multiply to get the final frequency */
  786. mpll_multiplier.u64 = csr_rd(CVMX_GSERX_DLMX_MPLL_MULTIPLIER(qlm, 0));
  787. freq = meas_refclock * mpll_multiplier.s.mpll_multiplier;
  788. freq = (freq + 500000) / 1000000;
  789. return freq;
  790. } else if (OCTEON_IS_MODEL(OCTEON_CN78XX)) {
  791. return cvmx_qlm_get_gbaud_mhz_node(cvmx_get_node_num(), qlm);
  792. } else if (OCTEON_IS_MODEL(OCTEON_CN73XX) || OCTEON_IS_MODEL(OCTEON_CNF75XX)) {
  793. cvmx_gserx_lane_mode_t lane_mode;
  794. lane_mode.u64 = csr_rd(CVMX_GSERX_LANE_MODE(qlm));
  795. switch (lane_mode.s.lmode) {
  796. case R_25G_REFCLK100:
  797. return 2500;
  798. case R_5G_REFCLK100:
  799. return 5000;
  800. case R_8G_REFCLK100:
  801. return 8000;
  802. case R_125G_REFCLK15625_KX:
  803. return 1250;
  804. case R_3125G_REFCLK15625_XAUI:
  805. return 3125;
  806. case R_103125G_REFCLK15625_KR:
  807. return 10312;
  808. case R_125G_REFCLK15625_SGMII:
  809. return 1250;
  810. case R_5G_REFCLK15625_QSGMII:
  811. return 5000;
  812. case R_625G_REFCLK15625_RXAUI:
  813. return 6250;
  814. case R_25G_REFCLK125:
  815. return 2500;
  816. case R_5G_REFCLK125:
  817. return 5000;
  818. case R_8G_REFCLK125:
  819. return 8000;
  820. default:
  821. return 0;
  822. }
  823. }
  824. return 0;
  825. }
  826. static enum cvmx_qlm_mode __cvmx_qlm_get_mode_cn70xx(int qlm)
  827. {
  828. switch (qlm) {
  829. case 0: /* DLM0/DLM1 - SGMII/QSGMII/RXAUI */
  830. {
  831. union cvmx_gmxx_inf_mode inf_mode0, inf_mode1;
  832. inf_mode0.u64 = csr_rd(CVMX_GMXX_INF_MODE(0));
  833. inf_mode1.u64 = csr_rd(CVMX_GMXX_INF_MODE(1));
  834. /* SGMII0 SGMII1 */
  835. switch (inf_mode0.s.mode) {
  836. case CVMX_GMX_INF_MODE_SGMII:
  837. switch (inf_mode1.s.mode) {
  838. case CVMX_GMX_INF_MODE_SGMII:
  839. return CVMX_QLM_MODE_SGMII_SGMII;
  840. case CVMX_GMX_INF_MODE_QSGMII:
  841. return CVMX_QLM_MODE_SGMII_QSGMII;
  842. default:
  843. return CVMX_QLM_MODE_SGMII_DISABLED;
  844. }
  845. case CVMX_GMX_INF_MODE_QSGMII:
  846. switch (inf_mode1.s.mode) {
  847. case CVMX_GMX_INF_MODE_SGMII:
  848. return CVMX_QLM_MODE_QSGMII_SGMII;
  849. case CVMX_GMX_INF_MODE_QSGMII:
  850. return CVMX_QLM_MODE_QSGMII_QSGMII;
  851. default:
  852. return CVMX_QLM_MODE_QSGMII_DISABLED;
  853. }
  854. case CVMX_GMX_INF_MODE_RXAUI:
  855. return CVMX_QLM_MODE_RXAUI_1X2;
  856. default:
  857. switch (inf_mode1.s.mode) {
  858. case CVMX_GMX_INF_MODE_SGMII:
  859. return CVMX_QLM_MODE_DISABLED_SGMII;
  860. case CVMX_GMX_INF_MODE_QSGMII:
  861. return CVMX_QLM_MODE_DISABLED_QSGMII;
  862. default:
  863. return CVMX_QLM_MODE_DISABLED;
  864. }
  865. }
  866. }
  867. case 1: /* Sata / pem0 */
  868. {
  869. union cvmx_gserx_sata_cfg sata_cfg;
  870. union cvmx_pemx_cfg pem0_cfg;
  871. sata_cfg.u64 = csr_rd(CVMX_GSERX_SATA_CFG(0));
  872. pem0_cfg.u64 = csr_rd(CVMX_PEMX_CFG(0));
  873. switch (pem0_cfg.cn70xx.md) {
  874. case CVMX_PEM_MD_GEN2_2LANE:
  875. case CVMX_PEM_MD_GEN1_2LANE:
  876. return CVMX_QLM_MODE_PCIE_1X2;
  877. case CVMX_PEM_MD_GEN2_1LANE:
  878. case CVMX_PEM_MD_GEN1_1LANE:
  879. if (sata_cfg.s.sata_en)
  880. /* Both PEM0 and PEM1 */
  881. return CVMX_QLM_MODE_PCIE_2X1;
  882. /* Only PEM0 */
  883. return CVMX_QLM_MODE_PCIE_1X1;
  884. case CVMX_PEM_MD_GEN2_4LANE:
  885. case CVMX_PEM_MD_GEN1_4LANE:
  886. return CVMX_QLM_MODE_PCIE;
  887. default:
  888. return CVMX_QLM_MODE_DISABLED;
  889. }
  890. }
  891. case 2: {
  892. union cvmx_gserx_sata_cfg sata_cfg;
  893. union cvmx_pemx_cfg pem0_cfg, pem1_cfg, pem2_cfg;
  894. sata_cfg.u64 = csr_rd(CVMX_GSERX_SATA_CFG(0));
  895. pem0_cfg.u64 = csr_rd(CVMX_PEMX_CFG(0));
  896. pem1_cfg.u64 = csr_rd(CVMX_PEMX_CFG(1));
  897. pem2_cfg.u64 = csr_rd(CVMX_PEMX_CFG(2));
  898. if (sata_cfg.s.sata_en)
  899. return CVMX_QLM_MODE_SATA_2X1;
  900. if (pem0_cfg.cn70xx.md == CVMX_PEM_MD_GEN2_4LANE ||
  901. pem0_cfg.cn70xx.md == CVMX_PEM_MD_GEN1_4LANE)
  902. return CVMX_QLM_MODE_PCIE;
  903. if (pem1_cfg.cn70xx.md == CVMX_PEM_MD_GEN2_2LANE ||
  904. pem1_cfg.cn70xx.md == CVMX_PEM_MD_GEN1_2LANE) {
  905. return CVMX_QLM_MODE_PCIE_1X2;
  906. }
  907. if (pem1_cfg.cn70xx.md == CVMX_PEM_MD_GEN2_1LANE ||
  908. pem1_cfg.cn70xx.md == CVMX_PEM_MD_GEN1_1LANE) {
  909. if (pem2_cfg.cn70xx.md == CVMX_PEM_MD_GEN2_1LANE ||
  910. pem2_cfg.cn70xx.md == CVMX_PEM_MD_GEN1_1LANE) {
  911. return CVMX_QLM_MODE_PCIE_2X1;
  912. } else {
  913. return CVMX_QLM_MODE_PCIE_1X1;
  914. }
  915. }
  916. if (pem2_cfg.cn70xx.md == CVMX_PEM_MD_GEN2_1LANE ||
  917. pem2_cfg.cn70xx.md == CVMX_PEM_MD_GEN1_1LANE)
  918. return CVMX_QLM_MODE_PCIE_2X1;
  919. return CVMX_QLM_MODE_DISABLED;
  920. }
  921. default:
  922. return CVMX_QLM_MODE_DISABLED;
  923. }
  924. return CVMX_QLM_MODE_DISABLED;
  925. }
  926. /*
  927. * Get the DLM mode for the interface based on the interface type.
  928. *
  929. * @param interface_type 0 - SGMII/QSGMII/RXAUI interface
  930. * 1 - PCIe
  931. * 2 - SATA
  932. * @param interface interface to use
  933. * Return: the qlm mode the interface is
  934. */
  935. enum cvmx_qlm_mode cvmx_qlm_get_dlm_mode(int interface_type, int interface)
  936. {
  937. switch (interface_type) {
  938. case 0: /* SGMII/QSGMII/RXAUI */
  939. {
  940. enum cvmx_qlm_mode qlm_mode = __cvmx_qlm_get_mode_cn70xx(0);
  941. switch (interface) {
  942. case 0:
  943. switch (qlm_mode) {
  944. case CVMX_QLM_MODE_SGMII_SGMII:
  945. case CVMX_QLM_MODE_SGMII_DISABLED:
  946. case CVMX_QLM_MODE_SGMII_QSGMII:
  947. return CVMX_QLM_MODE_SGMII;
  948. case CVMX_QLM_MODE_QSGMII_QSGMII:
  949. case CVMX_QLM_MODE_QSGMII_DISABLED:
  950. case CVMX_QLM_MODE_QSGMII_SGMII:
  951. return CVMX_QLM_MODE_QSGMII;
  952. case CVMX_QLM_MODE_RXAUI_1X2:
  953. return CVMX_QLM_MODE_RXAUI;
  954. default:
  955. return CVMX_QLM_MODE_DISABLED;
  956. }
  957. case 1:
  958. switch (qlm_mode) {
  959. case CVMX_QLM_MODE_SGMII_SGMII:
  960. case CVMX_QLM_MODE_DISABLED_SGMII:
  961. case CVMX_QLM_MODE_QSGMII_SGMII:
  962. return CVMX_QLM_MODE_SGMII;
  963. case CVMX_QLM_MODE_QSGMII_QSGMII:
  964. case CVMX_QLM_MODE_DISABLED_QSGMII:
  965. case CVMX_QLM_MODE_SGMII_QSGMII:
  966. return CVMX_QLM_MODE_QSGMII;
  967. default:
  968. return CVMX_QLM_MODE_DISABLED;
  969. }
  970. default:
  971. return qlm_mode;
  972. }
  973. }
  974. case 1: /* PCIe */
  975. {
  976. enum cvmx_qlm_mode qlm_mode1 = __cvmx_qlm_get_mode_cn70xx(1);
  977. enum cvmx_qlm_mode qlm_mode2 = __cvmx_qlm_get_mode_cn70xx(2);
  978. switch (interface) {
  979. case 0: /* PCIe0 can be DLM1 with 1, 2 or 4 lanes */
  980. return qlm_mode1;
  981. case 1:
  982. /*
  983. * PCIe1 can be in DLM1 1 lane(1), DLM2 1 lane(0)
  984. * or 2 lanes(0-1)
  985. */
  986. if (qlm_mode1 == CVMX_QLM_MODE_PCIE_2X1)
  987. return CVMX_QLM_MODE_PCIE_2X1;
  988. else if (qlm_mode2 == CVMX_QLM_MODE_PCIE_1X2 ||
  989. qlm_mode2 == CVMX_QLM_MODE_PCIE_2X1)
  990. return qlm_mode2;
  991. else
  992. return CVMX_QLM_MODE_DISABLED;
  993. case 2: /* PCIe2 can be DLM2 1 lanes(1) */
  994. if (qlm_mode2 == CVMX_QLM_MODE_PCIE_2X1)
  995. return qlm_mode2;
  996. else
  997. return CVMX_QLM_MODE_DISABLED;
  998. default:
  999. return CVMX_QLM_MODE_DISABLED;
  1000. }
  1001. }
  1002. case 2: /* SATA */
  1003. {
  1004. enum cvmx_qlm_mode qlm_mode = __cvmx_qlm_get_mode_cn70xx(2);
  1005. if (qlm_mode == CVMX_QLM_MODE_SATA_2X1)
  1006. return CVMX_QLM_MODE_SATA_2X1;
  1007. else
  1008. return CVMX_QLM_MODE_DISABLED;
  1009. }
  1010. default:
  1011. return CVMX_QLM_MODE_DISABLED;
  1012. }
  1013. }
  1014. static enum cvmx_qlm_mode __cvmx_qlm_get_mode_cn6xxx(int qlm)
  1015. {
  1016. cvmx_mio_qlmx_cfg_t qlmx_cfg;
  1017. if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
  1018. qlmx_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(qlm));
  1019. /* QLM is disabled when QLM SPD is 15. */
  1020. if (qlmx_cfg.s.qlm_spd == 15)
  1021. return CVMX_QLM_MODE_DISABLED;
  1022. switch (qlmx_cfg.s.qlm_cfg) {
  1023. case 0: /* PCIE */
  1024. return CVMX_QLM_MODE_PCIE;
  1025. case 1: /* ILK */
  1026. return CVMX_QLM_MODE_ILK;
  1027. case 2: /* SGMII */
  1028. return CVMX_QLM_MODE_SGMII;
  1029. case 3: /* XAUI */
  1030. return CVMX_QLM_MODE_XAUI;
  1031. case 7: /* RXAUI */
  1032. return CVMX_QLM_MODE_RXAUI;
  1033. default:
  1034. return CVMX_QLM_MODE_DISABLED;
  1035. }
  1036. } else if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
  1037. qlmx_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(qlm));
  1038. /* QLM is disabled when QLM SPD is 15. */
  1039. if (qlmx_cfg.s.qlm_spd == 15)
  1040. return CVMX_QLM_MODE_DISABLED;
  1041. switch (qlmx_cfg.s.qlm_cfg) {
  1042. case 0x9: /* SGMII */
  1043. return CVMX_QLM_MODE_SGMII;
  1044. case 0xb: /* XAUI */
  1045. return CVMX_QLM_MODE_XAUI;
  1046. case 0x0: /* PCIE gen2 */
  1047. case 0x8: /* PCIE gen2 (alias) */
  1048. case 0x2: /* PCIE gen1 */
  1049. case 0xa: /* PCIE gen1 (alias) */
  1050. return CVMX_QLM_MODE_PCIE;
  1051. case 0x1: /* SRIO 1x4 short */
  1052. case 0x3: /* SRIO 1x4 long */
  1053. return CVMX_QLM_MODE_SRIO_1X4;
  1054. case 0x4: /* SRIO 2x2 short */
  1055. case 0x6: /* SRIO 2x2 long */
  1056. return CVMX_QLM_MODE_SRIO_2X2;
  1057. case 0x5: /* SRIO 4x1 short */
  1058. case 0x7: /* SRIO 4x1 long */
  1059. if (!OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_0))
  1060. return CVMX_QLM_MODE_SRIO_4X1;
  1061. fallthrough;
  1062. default:
  1063. return CVMX_QLM_MODE_DISABLED;
  1064. }
  1065. } else if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
  1066. cvmx_sriox_status_reg_t status_reg;
  1067. /* For now skip qlm2 */
  1068. if (qlm == 2) {
  1069. cvmx_gmxx_inf_mode_t inf_mode;
  1070. inf_mode.u64 = csr_rd(CVMX_GMXX_INF_MODE(0));
  1071. if (inf_mode.s.speed == 15)
  1072. return CVMX_QLM_MODE_DISABLED;
  1073. else if (inf_mode.s.mode == 0)
  1074. return CVMX_QLM_MODE_SGMII;
  1075. else
  1076. return CVMX_QLM_MODE_XAUI;
  1077. }
  1078. status_reg.u64 = csr_rd(CVMX_SRIOX_STATUS_REG(qlm));
  1079. if (status_reg.s.srio)
  1080. return CVMX_QLM_MODE_SRIO_1X4;
  1081. else
  1082. return CVMX_QLM_MODE_PCIE;
  1083. } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
  1084. qlmx_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(qlm));
  1085. /* QLM is disabled when QLM SPD is 15. */
  1086. if (qlmx_cfg.s.qlm_spd == 15)
  1087. return CVMX_QLM_MODE_DISABLED;
  1088. switch (qlm) {
  1089. case 0:
  1090. switch (qlmx_cfg.s.qlm_cfg) {
  1091. case 0: /* PCIe 1x4 gen2 / gen1 */
  1092. return CVMX_QLM_MODE_PCIE;
  1093. case 2: /* SGMII */
  1094. return CVMX_QLM_MODE_SGMII;
  1095. case 3: /* XAUI */
  1096. return CVMX_QLM_MODE_XAUI;
  1097. default:
  1098. return CVMX_QLM_MODE_DISABLED;
  1099. }
  1100. break;
  1101. case 1:
  1102. switch (qlmx_cfg.s.qlm_cfg) {
  1103. case 0: /* PCIe 1x2 gen2 / gen1 */
  1104. return CVMX_QLM_MODE_PCIE_1X2;
  1105. case 1: /* PCIe 2x1 gen2 / gen1 */
  1106. return CVMX_QLM_MODE_PCIE_2X1;
  1107. default:
  1108. return CVMX_QLM_MODE_DISABLED;
  1109. }
  1110. break;
  1111. case 2:
  1112. switch (qlmx_cfg.s.qlm_cfg) {
  1113. case 2: /* SGMII */
  1114. return CVMX_QLM_MODE_SGMII;
  1115. case 3: /* XAUI */
  1116. return CVMX_QLM_MODE_XAUI;
  1117. default:
  1118. return CVMX_QLM_MODE_DISABLED;
  1119. }
  1120. break;
  1121. }
  1122. } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
  1123. qlmx_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(qlm));
  1124. /* QLM is disabled when QLM SPD is 15. */
  1125. if (qlmx_cfg.s.qlm_spd == 15)
  1126. return CVMX_QLM_MODE_DISABLED;
  1127. switch (qlm) {
  1128. case 0:
  1129. if (qlmx_cfg.s.qlm_cfg == 2) /* SGMII */
  1130. return CVMX_QLM_MODE_SGMII;
  1131. break;
  1132. case 1:
  1133. switch (qlmx_cfg.s.qlm_cfg) {
  1134. case 0: /* PCIe 1x2 gen2 / gen1 */
  1135. return CVMX_QLM_MODE_PCIE_1X2;
  1136. case 1: /* PCIe 2x1 gen2 / gen1 */
  1137. return CVMX_QLM_MODE_PCIE_2X1;
  1138. default:
  1139. return CVMX_QLM_MODE_DISABLED;
  1140. }
  1141. break;
  1142. }
  1143. }
  1144. return CVMX_QLM_MODE_DISABLED;
  1145. }
  1146. /**
  1147. * @INTERNAL
  1148. * Decrement the MPLL Multiplier for the DLM as per Errata G-20669
  1149. *
  1150. * @param qlm DLM to configure
  1151. * @param baud_mhz Speed of the DLM configured at
  1152. * @param old_multiplier MPLL_MULTIPLIER value to decrement
  1153. */
  1154. void __cvmx_qlm_set_mult(int qlm, int baud_mhz, int old_multiplier)
  1155. {
  1156. cvmx_gserx_dlmx_mpll_multiplier_t mpll_multiplier;
  1157. cvmx_gserx_dlmx_ref_clkdiv2_t clkdiv;
  1158. u64 meas_refclock, mult;
  1159. if (!OCTEON_IS_MODEL(OCTEON_CN70XX))
  1160. return;
  1161. if (qlm == -1)
  1162. return;
  1163. meas_refclock = cvmx_qlm_measure_clock(qlm);
  1164. if (meas_refclock == 0) {
  1165. printf("DLM%d: Reference clock not running\n", qlm);
  1166. return;
  1167. }
  1168. /*
  1169. * The baud rate multiplier needs to be adjusted on the CN70XX if
  1170. * the reference clock is > 100MHz.
  1171. */
  1172. if (qlm == 0) {
  1173. clkdiv.u64 = csr_rd(CVMX_GSERX_DLMX_REF_CLKDIV2(qlm, 0));
  1174. if (clkdiv.s.ref_clkdiv2)
  1175. baud_mhz *= 2;
  1176. }
  1177. mult = (uint64_t)baud_mhz * 1000000 + (meas_refclock / 2);
  1178. mult /= meas_refclock;
  1179. /*
  1180. * 6. Decrease MPLL_MULTIPLIER by one continually until it reaches
  1181. * the desired long-term setting, ensuring that each MPLL_MULTIPLIER
  1182. * value is constant for at least 1 msec before changing to the next
  1183. * value. The desired long-term setting is as indicated in HRM tables
  1184. * 21-1, 21-2, and 21-3. This is not required with the HRM
  1185. * sequence.
  1186. */
  1187. do {
  1188. mpll_multiplier.u64 = csr_rd(CVMX_GSERX_DLMX_MPLL_MULTIPLIER(qlm, 0));
  1189. mpll_multiplier.s.mpll_multiplier = --old_multiplier;
  1190. csr_wr(CVMX_GSERX_DLMX_MPLL_MULTIPLIER(qlm, 0), mpll_multiplier.u64);
  1191. /* Wait for 1 ms */
  1192. udelay(1000);
  1193. } while (old_multiplier > (int)mult);
  1194. }
  1195. enum cvmx_qlm_mode cvmx_qlm_get_mode_cn78xx(int node, int qlm)
  1196. {
  1197. cvmx_gserx_cfg_t gserx_cfg;
  1198. int qlm_mode[2][9] = { { -1, -1, -1, -1, -1, -1, -1, -1 },
  1199. { -1, -1, -1, -1, -1, -1, -1, -1 } };
  1200. if (qlm >= 8)
  1201. return CVMX_QLM_MODE_OCI;
  1202. if (qlm_mode[node][qlm] != -1)
  1203. return qlm_mode[node][qlm];
  1204. gserx_cfg.u64 = csr_rd_node(node, CVMX_GSERX_CFG(qlm));
  1205. if (gserx_cfg.s.pcie) {
  1206. switch (qlm) {
  1207. case 0: /* Either PEM0 x4 or PEM0 x8 */
  1208. case 1: /* Either PEM0 x8 or PEM1 x4 */
  1209. {
  1210. cvmx_pemx_cfg_t pemx_cfg;
  1211. pemx_cfg.u64 = csr_rd_node(node, CVMX_PEMX_CFG(0));
  1212. if (pemx_cfg.cn78xx.lanes8) {
  1213. /* PEM0 x8 */
  1214. qlm_mode[node][qlm] = CVMX_QLM_MODE_PCIE_1X8;
  1215. } else {
  1216. /* PEM0 x4 */
  1217. qlm_mode[node][qlm] = CVMX_QLM_MODE_PCIE;
  1218. }
  1219. break;
  1220. }
  1221. case 2: /* Either PEM2 x4 or PEM2 x8 */
  1222. {
  1223. cvmx_pemx_cfg_t pemx_cfg;
  1224. pemx_cfg.u64 = csr_rd_node(node, CVMX_PEMX_CFG(2));
  1225. if (pemx_cfg.cn78xx.lanes8) {
  1226. /* PEM2 x8 */
  1227. qlm_mode[node][qlm] = CVMX_QLM_MODE_PCIE_1X8;
  1228. } else {
  1229. /* PEM2 x4 */
  1230. qlm_mode[node][qlm] = CVMX_QLM_MODE_PCIE;
  1231. }
  1232. break;
  1233. }
  1234. case 3: /* Either PEM2 x8 or PEM3 x4 or PEM3 x8 */
  1235. {
  1236. cvmx_pemx_cfg_t pemx_cfg;
  1237. pemx_cfg.u64 = csr_rd_node(node, CVMX_PEMX_CFG(2));
  1238. if (pemx_cfg.cn78xx.lanes8) {
  1239. /* PEM2 x8 */
  1240. qlm_mode[node][qlm] = CVMX_QLM_MODE_PCIE_1X8;
  1241. }
  1242. /* Can be first 4 lanes of PEM3 */
  1243. pemx_cfg.u64 = csr_rd_node(node, CVMX_PEMX_CFG(3));
  1244. if (pemx_cfg.cn78xx.lanes8) {
  1245. /* PEM3 x8 */
  1246. qlm_mode[node][qlm] = CVMX_QLM_MODE_PCIE_1X8;
  1247. } else {
  1248. /* PEM2 x4 */
  1249. qlm_mode[node][qlm] = CVMX_QLM_MODE_PCIE;
  1250. }
  1251. break;
  1252. }
  1253. case 4: /* Either PEM3 x8 or PEM3 x4 */
  1254. {
  1255. cvmx_pemx_cfg_t pemx_cfg;
  1256. pemx_cfg.u64 = csr_rd_node(node, CVMX_PEMX_CFG(3));
  1257. if (pemx_cfg.cn78xx.lanes8) {
  1258. /* PEM3 x8 */
  1259. qlm_mode[node][qlm] = CVMX_QLM_MODE_PCIE_1X8;
  1260. } else {
  1261. /* PEM3 x4 */
  1262. qlm_mode[node][qlm] = CVMX_QLM_MODE_PCIE;
  1263. }
  1264. break;
  1265. }
  1266. default:
  1267. qlm_mode[node][qlm] = CVMX_QLM_MODE_DISABLED;
  1268. break;
  1269. }
  1270. } else if (gserx_cfg.s.ila) {
  1271. qlm_mode[node][qlm] = CVMX_QLM_MODE_ILK;
  1272. } else if (gserx_cfg.s.bgx) {
  1273. cvmx_bgxx_cmrx_config_t cmr_config;
  1274. cvmx_bgxx_spux_br_pmd_control_t pmd_control;
  1275. int bgx = (qlm < 2) ? qlm : qlm - 2;
  1276. cmr_config.u64 = csr_rd_node(node, CVMX_BGXX_CMRX_CONFIG(0, bgx));
  1277. pmd_control.u64 = csr_rd_node(node, CVMX_BGXX_SPUX_BR_PMD_CONTROL(0, bgx));
  1278. switch (cmr_config.s.lmac_type) {
  1279. case 0:
  1280. qlm_mode[node][qlm] = CVMX_QLM_MODE_SGMII;
  1281. break;
  1282. case 1:
  1283. qlm_mode[node][qlm] = CVMX_QLM_MODE_XAUI;
  1284. break;
  1285. case 2:
  1286. qlm_mode[node][qlm] = CVMX_QLM_MODE_RXAUI;
  1287. break;
  1288. case 3:
  1289. /*
  1290. * Use training to determine if we're in 10GBASE-KR
  1291. * or XFI
  1292. */
  1293. if (pmd_control.s.train_en)
  1294. qlm_mode[node][qlm] = CVMX_QLM_MODE_10G_KR;
  1295. else
  1296. qlm_mode[node][qlm] = CVMX_QLM_MODE_XFI;
  1297. break;
  1298. case 4:
  1299. /*
  1300. * Use training to determine if we're in 40GBASE-KR
  1301. * or XLAUI
  1302. */
  1303. if (pmd_control.s.train_en)
  1304. qlm_mode[node][qlm] = CVMX_QLM_MODE_40G_KR4;
  1305. else
  1306. qlm_mode[node][qlm] = CVMX_QLM_MODE_XLAUI;
  1307. break;
  1308. default:
  1309. qlm_mode[node][qlm] = CVMX_QLM_MODE_DISABLED;
  1310. break;
  1311. }
  1312. } else {
  1313. qlm_mode[node][qlm] = CVMX_QLM_MODE_DISABLED;
  1314. }
  1315. return qlm_mode[node][qlm];
  1316. }
  1317. enum cvmx_qlm_mode __cvmx_qlm_get_mode_cn73xx(int qlm)
  1318. {
  1319. cvmx_gserx_cfg_t gserx_cfg;
  1320. int qlm_mode[7] = { -1, -1, -1, -1, -1, -1, -1 };
  1321. if (qlm_mode[qlm] != -1)
  1322. return qlm_mode[qlm];
  1323. if (qlm > 6) {
  1324. debug("Invalid QLM(%d) passed\n", qlm);
  1325. return -1;
  1326. }
  1327. gserx_cfg.u64 = csr_rd(CVMX_GSERX_CFG(qlm));
  1328. if (gserx_cfg.s.pcie) {
  1329. cvmx_pemx_cfg_t pemx_cfg;
  1330. switch (qlm) {
  1331. case 0: /* Either PEM0 x4 or PEM0 x8 */
  1332. case 1: /* Either PEM0 x8 or PEM1 x4 */
  1333. {
  1334. pemx_cfg.u64 = csr_rd(CVMX_PEMX_CFG(0));
  1335. if (pemx_cfg.cn78xx.lanes8) {
  1336. /* PEM0 x8 */
  1337. qlm_mode[qlm] = CVMX_QLM_MODE_PCIE_1X8;
  1338. } else {
  1339. /* PEM0/PEM1 x4 */
  1340. qlm_mode[qlm] = CVMX_QLM_MODE_PCIE;
  1341. }
  1342. break;
  1343. }
  1344. case 2: /* Either PEM2 x4 or PEM2 x8 */
  1345. {
  1346. pemx_cfg.u64 = csr_rd(CVMX_PEMX_CFG(2));
  1347. if (pemx_cfg.cn78xx.lanes8) {
  1348. /* PEM2 x8 */
  1349. qlm_mode[qlm] = CVMX_QLM_MODE_PCIE_1X8;
  1350. } else {
  1351. /* PEM2 x4 */
  1352. qlm_mode[qlm] = CVMX_QLM_MODE_PCIE;
  1353. }
  1354. break;
  1355. }
  1356. case 5:
  1357. case 6: /* PEM3 x2 */
  1358. qlm_mode[qlm] = CVMX_QLM_MODE_PCIE_1X2; /* PEM3 x2 */
  1359. break;
  1360. case 3: /* Either PEM2 x8 or PEM3 x4 */
  1361. {
  1362. pemx_cfg.u64 = csr_rd(CVMX_PEMX_CFG(2));
  1363. if (pemx_cfg.cn78xx.lanes8) {
  1364. /* PEM2 x8 */
  1365. qlm_mode[qlm] = CVMX_QLM_MODE_PCIE_1X8;
  1366. } else {
  1367. /* PEM3 x4 */
  1368. qlm_mode[qlm] = CVMX_QLM_MODE_PCIE;
  1369. }
  1370. break;
  1371. }
  1372. default:
  1373. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1374. break;
  1375. }
  1376. } else if (gserx_cfg.s.bgx) {
  1377. cvmx_bgxx_cmrx_config_t cmr_config;
  1378. cvmx_bgxx_cmr_rx_lmacs_t bgx_cmr_rx_lmacs;
  1379. cvmx_bgxx_spux_br_pmd_control_t pmd_control;
  1380. int bgx = 0;
  1381. int start = 0, end = 4, index;
  1382. int lane_mask = 0, train_mask = 0;
  1383. int mux = 0; // 0:BGX2 (DLM5/DLM6), 1:BGX2(DLM5), 2:BGX2(DLM6)
  1384. if (qlm < 4) {
  1385. bgx = qlm - 2;
  1386. } else if (qlm == 5 || qlm == 6) {
  1387. bgx = 2;
  1388. mux = cvmx_qlm_mux_interface(bgx);
  1389. if (mux == 0) {
  1390. start = 0;
  1391. end = 4;
  1392. } else if (mux == 1) {
  1393. start = 0;
  1394. end = 2;
  1395. } else if (mux == 2) {
  1396. start = 2;
  1397. end = 4;
  1398. } else {
  1399. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1400. return qlm_mode[qlm];
  1401. }
  1402. }
  1403. for (index = start; index < end; index++) {
  1404. cmr_config.u64 = csr_rd(CVMX_BGXX_CMRX_CONFIG(index, bgx));
  1405. pmd_control.u64 = csr_rd(CVMX_BGXX_SPUX_BR_PMD_CONTROL(index, bgx));
  1406. lane_mask |= (cmr_config.s.lmac_type << (index * 4));
  1407. train_mask |= (pmd_control.s.train_en << (index * 4));
  1408. }
  1409. /* Need to include DLM5 lmacs when only DLM6 DLM is used */
  1410. if (mux == 2)
  1411. bgx_cmr_rx_lmacs.u64 = csr_rd(CVMX_BGXX_CMR_RX_LMACS(2));
  1412. switch (lane_mask) {
  1413. case 0:
  1414. if (mux == 1) {
  1415. qlm_mode[qlm] = CVMX_QLM_MODE_SGMII_2X1;
  1416. } else if (mux == 2) {
  1417. qlm_mode[qlm] = CVMX_QLM_MODE_SGMII_2X1;
  1418. bgx_cmr_rx_lmacs.s.lmacs = 4;
  1419. }
  1420. qlm_mode[qlm] = CVMX_QLM_MODE_SGMII;
  1421. break;
  1422. case 0x1:
  1423. qlm_mode[qlm] = CVMX_QLM_MODE_XAUI;
  1424. break;
  1425. case 0x2:
  1426. if (mux == 1) {
  1427. // NONE+RXAUI
  1428. qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI_1X2;
  1429. } else if (mux == 0) {
  1430. // RXAUI+SGMII
  1431. qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
  1432. } else {
  1433. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1434. }
  1435. break;
  1436. case 0x202:
  1437. if (mux == 2) {
  1438. // RXAUI+RXAUI
  1439. qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI_1X2;
  1440. bgx_cmr_rx_lmacs.s.lmacs = 4;
  1441. } else if (mux == 1) {
  1442. // RXAUI+RXAUI
  1443. qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI_1X2;
  1444. } else if (mux == 0) {
  1445. qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI;
  1446. } else {
  1447. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1448. }
  1449. break;
  1450. case 0x22:
  1451. qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI;
  1452. break;
  1453. case 0x3333:
  1454. /*
  1455. * Use training to determine if we're in 10GBASE-KR
  1456. * or XFI
  1457. */
  1458. if (train_mask)
  1459. qlm_mode[qlm] = CVMX_QLM_MODE_10G_KR;
  1460. else
  1461. qlm_mode[qlm] = CVMX_QLM_MODE_XFI;
  1462. break;
  1463. case 0x4:
  1464. /*
  1465. * Use training to determine if we're in 40GBASE-KR
  1466. * or XLAUI
  1467. */
  1468. if (train_mask)
  1469. qlm_mode[qlm] = CVMX_QLM_MODE_40G_KR4;
  1470. else
  1471. qlm_mode[qlm] = CVMX_QLM_MODE_XLAUI;
  1472. break;
  1473. case 0x0005:
  1474. qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_SGMII;
  1475. break;
  1476. case 0x3335:
  1477. if (train_mask)
  1478. qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_10G_KR;
  1479. else
  1480. qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_XFI;
  1481. break;
  1482. case 0x45:
  1483. if (train_mask)
  1484. qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_40G_KR4;
  1485. else
  1486. qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_XLAUI;
  1487. break;
  1488. case 0x225:
  1489. qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_RXAUI;
  1490. break;
  1491. case 0x15:
  1492. qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_XAUI;
  1493. break;
  1494. case 0x200:
  1495. if (mux == 2) {
  1496. qlm_mode[qlm] = CVMX_QLM_MODE_RXAUI_1X2;
  1497. bgx_cmr_rx_lmacs.s.lmacs = 4;
  1498. } else
  1499. case 0x205:
  1500. case 0x233:
  1501. case 0x3302:
  1502. case 0x3305:
  1503. if (mux == 0)
  1504. qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
  1505. else
  1506. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1507. break;
  1508. case 0x3300:
  1509. if (mux == 0) {
  1510. qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
  1511. } else if (mux == 2) {
  1512. if (train_mask)
  1513. qlm_mode[qlm] = CVMX_QLM_MODE_10G_KR_1X2;
  1514. else
  1515. qlm_mode[qlm] = CVMX_QLM_MODE_XFI_1X2;
  1516. bgx_cmr_rx_lmacs.s.lmacs = 4;
  1517. } else {
  1518. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1519. }
  1520. break;
  1521. case 0x33:
  1522. if (mux == 1 || mux == 2) {
  1523. if (train_mask)
  1524. qlm_mode[qlm] = CVMX_QLM_MODE_10G_KR_1X2;
  1525. else
  1526. qlm_mode[qlm] = CVMX_QLM_MODE_XFI_1X2;
  1527. if (mux == 2)
  1528. bgx_cmr_rx_lmacs.s.lmacs = 4;
  1529. } else {
  1530. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1531. }
  1532. break;
  1533. case 0x0035:
  1534. if (mux == 0)
  1535. qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
  1536. else if (train_mask)
  1537. qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_10G_KR_1X1;
  1538. else
  1539. qlm_mode[qlm] = CVMX_QLM_MODE_RGMII_XFI_1X1;
  1540. break;
  1541. case 0x235:
  1542. if (mux == 0)
  1543. qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
  1544. else
  1545. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1546. break;
  1547. default:
  1548. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1549. break;
  1550. }
  1551. if (mux == 2) {
  1552. csr_wr(CVMX_BGXX_CMR_RX_LMACS(2), bgx_cmr_rx_lmacs.u64);
  1553. csr_wr(CVMX_BGXX_CMR_TX_LMACS(2), bgx_cmr_rx_lmacs.u64);
  1554. }
  1555. } else if (gserx_cfg.s.sata) {
  1556. qlm_mode[qlm] = CVMX_QLM_MODE_SATA_2X1;
  1557. } else {
  1558. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1559. }
  1560. return qlm_mode[qlm];
  1561. }
  1562. enum cvmx_qlm_mode __cvmx_qlm_get_mode_cnf75xx(int qlm)
  1563. {
  1564. cvmx_gserx_cfg_t gserx_cfg;
  1565. int qlm_mode[9] = { -1, -1, -1, -1, -1, -1, -1 };
  1566. if (qlm_mode[qlm] != -1)
  1567. return qlm_mode[qlm];
  1568. if (qlm > 9) {
  1569. debug("Invalid QLM(%d) passed\n", qlm);
  1570. return -1;
  1571. }
  1572. if ((qlm == 2 || qlm == 3) && (OCTEON_IS_MODEL(OCTEON_CNF75XX))) {
  1573. cvmx_sriox_status_reg_t status_reg;
  1574. int port = (qlm == 2) ? 0 : 1;
  1575. status_reg.u64 = csr_rd(CVMX_SRIOX_STATUS_REG(port));
  1576. /* FIXME add different width */
  1577. if (status_reg.s.srio)
  1578. qlm_mode[qlm] = CVMX_QLM_MODE_SRIO_1X4;
  1579. else
  1580. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1581. return qlm_mode[qlm];
  1582. }
  1583. gserx_cfg.u64 = csr_rd(CVMX_GSERX_CFG(qlm));
  1584. if (gserx_cfg.s.pcie) {
  1585. switch (qlm) {
  1586. case 0: /* Either PEM0 x2 or PEM0 x4 */
  1587. case 1: /* Either PEM1 x2 or PEM0 x4 */
  1588. {
  1589. /* FIXME later */
  1590. qlm_mode[qlm] = CVMX_QLM_MODE_PCIE;
  1591. break;
  1592. }
  1593. default:
  1594. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1595. break;
  1596. }
  1597. } else if (gserx_cfg.s.bgx) {
  1598. cvmx_bgxx_cmrx_config_t cmr_config;
  1599. cvmx_bgxx_spux_br_pmd_control_t pmd_control;
  1600. int bgx = 0;
  1601. int start = 0, end = 4, index;
  1602. int lane_mask = 0, train_mask = 0;
  1603. int mux = 0; // 0:BGX0 (DLM4/DLM5), 1:BGX0(DLM4), 2:BGX0(DLM5)
  1604. cvmx_gserx_cfg_t gser1, gser2;
  1605. gser1.u64 = csr_rd(CVMX_GSERX_CFG(4));
  1606. gser2.u64 = csr_rd(CVMX_GSERX_CFG(5));
  1607. if (gser1.s.bgx && gser2.s.bgx) {
  1608. start = 0;
  1609. end = 4;
  1610. } else if (gser1.s.bgx) {
  1611. start = 0;
  1612. end = 2;
  1613. mux = 1;
  1614. } else if (gser2.s.bgx) {
  1615. start = 2;
  1616. end = 4;
  1617. mux = 2;
  1618. } else {
  1619. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1620. return qlm_mode[qlm];
  1621. }
  1622. for (index = start; index < end; index++) {
  1623. cmr_config.u64 = csr_rd(CVMX_BGXX_CMRX_CONFIG(index, bgx));
  1624. pmd_control.u64 = csr_rd(CVMX_BGXX_SPUX_BR_PMD_CONTROL(index, bgx));
  1625. lane_mask |= (cmr_config.s.lmac_type << (index * 4));
  1626. train_mask |= (pmd_control.s.train_en << (index * 4));
  1627. }
  1628. switch (lane_mask) {
  1629. case 0:
  1630. if (mux == 1 || mux == 2)
  1631. qlm_mode[qlm] = CVMX_QLM_MODE_SGMII_2X1;
  1632. else
  1633. qlm_mode[qlm] = CVMX_QLM_MODE_SGMII;
  1634. break;
  1635. case 0x3300:
  1636. if (mux == 0)
  1637. qlm_mode[qlm] = CVMX_QLM_MODE_MIXED;
  1638. else if (mux == 2)
  1639. if (train_mask)
  1640. qlm_mode[qlm] = CVMX_QLM_MODE_10G_KR_1X2;
  1641. else
  1642. qlm_mode[qlm] = CVMX_QLM_MODE_XFI_1X2;
  1643. else
  1644. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1645. break;
  1646. default:
  1647. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1648. break;
  1649. }
  1650. } else {
  1651. qlm_mode[qlm] = CVMX_QLM_MODE_DISABLED;
  1652. }
  1653. return qlm_mode[qlm];
  1654. }
  1655. /*
  1656. * Read QLM and return mode.
  1657. */
  1658. enum cvmx_qlm_mode cvmx_qlm_get_mode(int qlm)
  1659. {
  1660. if (OCTEON_IS_OCTEON2())
  1661. return __cvmx_qlm_get_mode_cn6xxx(qlm);
  1662. else if (OCTEON_IS_MODEL(OCTEON_CN70XX))
  1663. return __cvmx_qlm_get_mode_cn70xx(qlm);
  1664. else if (OCTEON_IS_MODEL(OCTEON_CN78XX))
  1665. return cvmx_qlm_get_mode_cn78xx(cvmx_get_node_num(), qlm);
  1666. else if (OCTEON_IS_MODEL(OCTEON_CN73XX))
  1667. return __cvmx_qlm_get_mode_cn73xx(qlm);
  1668. else if (OCTEON_IS_MODEL(OCTEON_CNF75XX))
  1669. return __cvmx_qlm_get_mode_cnf75xx(qlm);
  1670. return CVMX_QLM_MODE_DISABLED;
  1671. }
  1672. int cvmx_qlm_measure_clock_cn7xxx(int node, int qlm)
  1673. {
  1674. cvmx_gserx_cfg_t cfg;
  1675. cvmx_gserx_refclk_sel_t refclk_sel;
  1676. cvmx_gserx_lane_mode_t lane_mode;
  1677. if (OCTEON_IS_MODEL(OCTEON_CN73XX)) {
  1678. if (node != 0 || qlm >= 7)
  1679. return -1;
  1680. } else if (OCTEON_IS_MODEL(OCTEON_CN78XX)) {
  1681. if (qlm >= 8 || node > 1)
  1682. return -1; /* FIXME for OCI */
  1683. } else {
  1684. debug("%s: Unsupported OCTEON model\n", __func__);
  1685. return -1;
  1686. }
  1687. cfg.u64 = csr_rd_node(node, CVMX_GSERX_CFG(qlm));
  1688. if (cfg.s.pcie) {
  1689. refclk_sel.u64 = csr_rd_node(node, CVMX_GSERX_REFCLK_SEL(qlm));
  1690. if (refclk_sel.s.pcie_refclk125)
  1691. return REF_125MHZ; /* Ref 125 Mhz */
  1692. else
  1693. return REF_100MHZ; /* Ref 100Mhz */
  1694. }
  1695. lane_mode.u64 = csr_rd_node(node, CVMX_GSERX_LANE_MODE(qlm));
  1696. switch (lane_mode.s.lmode) {
  1697. case R_25G_REFCLK100:
  1698. return REF_100MHZ;
  1699. case R_5G_REFCLK100:
  1700. return REF_100MHZ;
  1701. case R_8G_REFCLK100:
  1702. return REF_100MHZ;
  1703. case R_125G_REFCLK15625_KX:
  1704. return REF_156MHZ;
  1705. case R_3125G_REFCLK15625_XAUI:
  1706. return REF_156MHZ;
  1707. case R_103125G_REFCLK15625_KR:
  1708. return REF_156MHZ;
  1709. case R_125G_REFCLK15625_SGMII:
  1710. return REF_156MHZ;
  1711. case R_5G_REFCLK15625_QSGMII:
  1712. return REF_156MHZ;
  1713. case R_625G_REFCLK15625_RXAUI:
  1714. return REF_156MHZ;
  1715. case R_25G_REFCLK125:
  1716. return REF_125MHZ;
  1717. case R_5G_REFCLK125:
  1718. return REF_125MHZ;
  1719. case R_8G_REFCLK125:
  1720. return REF_125MHZ;
  1721. default:
  1722. return 0;
  1723. }
  1724. }
  1725. /**
  1726. * Measure the reference clock of a QLM on a multi-node setup
  1727. *
  1728. * @param node node to measure
  1729. * @param qlm QLM to measure
  1730. *
  1731. * Return: Clock rate in Hz
  1732. */
  1733. int cvmx_qlm_measure_clock_node(int node, int qlm)
  1734. {
  1735. if (octeon_has_feature(OCTEON_FEATURE_MULTINODE))
  1736. return cvmx_qlm_measure_clock_cn7xxx(node, qlm);
  1737. else
  1738. return cvmx_qlm_measure_clock(qlm);
  1739. }
  1740. /**
  1741. * Measure the reference clock of a QLM
  1742. *
  1743. * @param qlm QLM to measure
  1744. *
  1745. * Return: Clock rate in Hz
  1746. */
  1747. int cvmx_qlm_measure_clock(int qlm)
  1748. {
  1749. cvmx_mio_ptp_clock_cfg_t ptp_clock;
  1750. u64 count;
  1751. u64 start_cycle, stop_cycle;
  1752. int evcnt_offset = 0x10;
  1753. int incr_count = 1;
  1754. int ref_clock[16] = { 0 };
  1755. if (ref_clock[qlm])
  1756. return ref_clock[qlm];
  1757. if (OCTEON_IS_OCTEON3() && !OCTEON_IS_MODEL(OCTEON_CN70XX))
  1758. return cvmx_qlm_measure_clock_cn7xxx(cvmx_get_node_num(), qlm);
  1759. if (OCTEON_IS_MODEL(OCTEON_CN70XX) && qlm == 0) {
  1760. cvmx_gserx_dlmx_ref_clkdiv2_t ref_clkdiv2;
  1761. ref_clkdiv2.u64 = csr_rd(CVMX_GSERX_DLMX_REF_CLKDIV2(qlm, 0));
  1762. if (ref_clkdiv2.s.ref_clkdiv2)
  1763. incr_count = 2;
  1764. }
  1765. /* Fix reference clock for OCI QLMs */
  1766. /* Disable the PTP event counter while we configure it */
  1767. ptp_clock.u64 = csr_rd(CVMX_MIO_PTP_CLOCK_CFG); /* For CN63XXp1 errata */
  1768. ptp_clock.s.evcnt_en = 0;
  1769. csr_wr(CVMX_MIO_PTP_CLOCK_CFG, ptp_clock.u64);
  1770. /* Count on rising edge, Choose which QLM to count */
  1771. ptp_clock.u64 = csr_rd(CVMX_MIO_PTP_CLOCK_CFG); /* For CN63XXp1 errata */
  1772. ptp_clock.s.evcnt_edge = 0;
  1773. ptp_clock.s.evcnt_in = evcnt_offset + qlm;
  1774. csr_wr(CVMX_MIO_PTP_CLOCK_CFG, ptp_clock.u64);
  1775. /* Clear MIO_PTP_EVT_CNT */
  1776. csr_rd(CVMX_MIO_PTP_EVT_CNT); /* For CN63XXp1 errata */
  1777. count = csr_rd(CVMX_MIO_PTP_EVT_CNT);
  1778. csr_wr(CVMX_MIO_PTP_EVT_CNT, -count);
  1779. /* Set MIO_PTP_EVT_CNT to 1 billion */
  1780. csr_wr(CVMX_MIO_PTP_EVT_CNT, 1000000000);
  1781. /* Enable the PTP event counter */
  1782. ptp_clock.u64 = csr_rd(CVMX_MIO_PTP_CLOCK_CFG); /* For CN63XXp1 errata */
  1783. ptp_clock.s.evcnt_en = 1;
  1784. csr_wr(CVMX_MIO_PTP_CLOCK_CFG, ptp_clock.u64);
  1785. start_cycle = get_ticks();
  1786. /* Wait for 50ms */
  1787. mdelay(50);
  1788. /* Read the counter */
  1789. csr_rd(CVMX_MIO_PTP_EVT_CNT); /* For CN63XXp1 errata */
  1790. count = csr_rd(CVMX_MIO_PTP_EVT_CNT);
  1791. stop_cycle = get_ticks();
  1792. /* Disable the PTP event counter */
  1793. ptp_clock.u64 = csr_rd(CVMX_MIO_PTP_CLOCK_CFG); /* For CN63XXp1 errata */
  1794. ptp_clock.s.evcnt_en = 0;
  1795. csr_wr(CVMX_MIO_PTP_CLOCK_CFG, ptp_clock.u64);
  1796. /* Clock counted down, so reverse it */
  1797. count = 1000000000 - count;
  1798. count *= incr_count;
  1799. /* Return the rate */
  1800. ref_clock[qlm] = count * gd->cpu_clk / (stop_cycle - start_cycle);
  1801. return ref_clock[qlm];
  1802. }
  1803. /*
  1804. * Perform RX equalization on a QLM
  1805. *
  1806. * @param node Node the QLM is on
  1807. * @param qlm QLM to perform RX equalization on
  1808. * @param lane Lane to use, or -1 for all lanes
  1809. *
  1810. * Return: Zero on success, negative if any lane failed RX equalization
  1811. */
  1812. int __cvmx_qlm_rx_equalization(int node, int qlm, int lane)
  1813. {
  1814. cvmx_gserx_phy_ctl_t phy_ctl;
  1815. cvmx_gserx_br_rxx_ctl_t rxx_ctl;
  1816. cvmx_gserx_br_rxx_eer_t rxx_eer;
  1817. cvmx_gserx_rx_eie_detsts_t eie_detsts;
  1818. int fail, gbaud, l, lane_mask;
  1819. enum cvmx_qlm_mode mode;
  1820. int max_lanes = cvmx_qlm_get_lanes(qlm);
  1821. cvmx_gserx_lane_mode_t lmode;
  1822. cvmx_gserx_lane_px_mode_1_t pmode_1;
  1823. int pending = 0;
  1824. u64 timeout;
  1825. /* Don't touch QLMs if it is reset or powered down */
  1826. phy_ctl.u64 = csr_rd_node(node, CVMX_GSERX_PHY_CTL(qlm));
  1827. if (phy_ctl.s.phy_pd || phy_ctl.s.phy_reset)
  1828. return -1;
  1829. /*
  1830. * Check whether GSER PRBS pattern matcher is enabled on any of the
  1831. * applicable lanes. Can't complete RX Equalization while pattern
  1832. * matcher is enabled because it causes errors
  1833. */
  1834. for (l = 0; l < max_lanes; l++) {
  1835. cvmx_gserx_lanex_lbert_cfg_t lbert_cfg;
  1836. if (lane != -1 && lane != l)
  1837. continue;
  1838. lbert_cfg.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_LBERT_CFG(l, qlm));
  1839. if (lbert_cfg.s.lbert_pm_en == 1)
  1840. return -1;
  1841. }
  1842. /* Get Lane Mode */
  1843. lmode.u64 = csr_rd_node(node, CVMX_GSERX_LANE_MODE(qlm));
  1844. /*
  1845. * Check to see if in VMA manual mode is set. If in VMA manual mode
  1846. * don't complete rx equalization
  1847. */
  1848. pmode_1.u64 = csr_rd_node(node, CVMX_GSERX_LANE_PX_MODE_1(lmode.s.lmode, qlm));
  1849. if (pmode_1.s.vma_mm == 1) {
  1850. #ifdef DEBUG_QLM
  1851. debug("N%d:QLM%d: VMA Manual (manual DFE) selected. Not completing Rx equalization\n",
  1852. node, qlm);
  1853. #endif
  1854. return 0;
  1855. }
  1856. if (OCTEON_IS_MODEL(OCTEON_CN78XX)) {
  1857. gbaud = cvmx_qlm_get_gbaud_mhz_node(node, qlm);
  1858. mode = cvmx_qlm_get_mode_cn78xx(node, qlm);
  1859. } else {
  1860. gbaud = cvmx_qlm_get_gbaud_mhz(qlm);
  1861. mode = cvmx_qlm_get_mode(qlm);
  1862. }
  1863. /* Apply RX Equalization for speed >= 8G */
  1864. if (qlm < 8) {
  1865. if (gbaud < 6250)
  1866. return 0;
  1867. }
  1868. /* Don't run on PCIe Links */
  1869. if (mode == CVMX_QLM_MODE_PCIE || mode == CVMX_QLM_MODE_PCIE_1X8 ||
  1870. mode == CVMX_QLM_MODE_PCIE_1X2 || mode == CVMX_QLM_MODE_PCIE_2X1)
  1871. return -1;
  1872. fail = 0;
  1873. /*
  1874. * Before completing Rx equalization wait for
  1875. * GSERx_RX_EIE_DETSTS[CDRLOCK] to be set.
  1876. * This ensures the rx data is valid
  1877. */
  1878. if (lane == -1) {
  1879. /*
  1880. * check all 4 Lanes (cdrlock = 1111/b) for CDR Lock with
  1881. * lane == -1
  1882. */
  1883. if (CVMX_WAIT_FOR_FIELD64_NODE(node, CVMX_GSERX_RX_EIE_DETSTS(qlm),
  1884. cvmx_gserx_rx_eie_detsts_t, cdrlock, ==,
  1885. (1 << max_lanes) - 1, 500)) {
  1886. #ifdef DEBUG_QLM
  1887. eie_detsts.u64 = csr_rd_node(node, CVMX_GSERX_RX_EIE_DETSTS(qlm));
  1888. debug("ERROR: %d:QLM%d: CDR Lock not detected for all 4 lanes. CDR_LOCK(0x%x)\n",
  1889. node, qlm, eie_detsts.s.cdrlock);
  1890. #endif
  1891. return -1;
  1892. }
  1893. } else {
  1894. if (CVMX_WAIT_FOR_FIELD64_NODE(node, CVMX_GSERX_RX_EIE_DETSTS(qlm),
  1895. cvmx_gserx_rx_eie_detsts_t, cdrlock, &, (1 << lane),
  1896. 500)) {
  1897. #ifdef DEBUG_QLM
  1898. eie_detsts.u64 = csr_rd_node(node, CVMX_GSERX_RX_EIE_DETSTS(qlm));
  1899. debug("ERROR: %d:QLM%d: CDR Lock not detected for Lane%d CDR_LOCK(0x%x)\n",
  1900. node, qlm, lane, eie_detsts.s.cdrlock);
  1901. #endif
  1902. return -1;
  1903. }
  1904. }
  1905. /*
  1906. * Errata (GSER-20075) GSER(0..13)_BR_RX3_EER[RXT_ERR] is
  1907. * GSER(0..13)_BR_RX2_EER[RXT_ERR]. Since lanes 2-3 trigger at the
  1908. * same time, we need to setup lane 3 before we loop through the lanes
  1909. */
  1910. if (OCTEON_IS_MODEL(OCTEON_CN78XX_PASS1_X) && (lane == -1 || lane == 3)) {
  1911. /* Enable software control */
  1912. rxx_ctl.u64 = csr_rd_node(node, CVMX_GSERX_BR_RXX_CTL(3, qlm));
  1913. rxx_ctl.s.rxt_swm = 1;
  1914. csr_wr_node(node, CVMX_GSERX_BR_RXX_CTL(3, qlm), rxx_ctl.u64);
  1915. /* Clear the completion flag */
  1916. rxx_eer.u64 = csr_rd_node(node, CVMX_GSERX_BR_RXX_EER(3, qlm));
  1917. rxx_eer.s.rxt_esv = 0;
  1918. csr_wr_node(node, CVMX_GSERX_BR_RXX_EER(3, qlm), rxx_eer.u64);
  1919. /* Initiate a new request on lane 2 */
  1920. if (lane == 3) {
  1921. rxx_eer.u64 = csr_rd_node(node, CVMX_GSERX_BR_RXX_EER(2, qlm));
  1922. rxx_eer.s.rxt_eer = 1;
  1923. csr_wr_node(node, CVMX_GSERX_BR_RXX_EER(2, qlm), rxx_eer.u64);
  1924. }
  1925. }
  1926. for (l = 0; l < max_lanes; l++) {
  1927. if (lane != -1 && lane != l)
  1928. continue;
  1929. /*
  1930. * Skip lane 3 on 78p1.x due to Errata (GSER-20075).
  1931. * Handled above
  1932. */
  1933. if (OCTEON_IS_MODEL(OCTEON_CN78XX_PASS1_X) && l == 3) {
  1934. /*
  1935. * Need to add lane 3 to pending list for 78xx
  1936. * pass 1.x
  1937. */
  1938. pending |= 1 << 3;
  1939. continue;
  1940. }
  1941. /* Enable software control */
  1942. rxx_ctl.u64 = csr_rd_node(node, CVMX_GSERX_BR_RXX_CTL(l, qlm));
  1943. rxx_ctl.s.rxt_swm = 1;
  1944. csr_wr_node(node, CVMX_GSERX_BR_RXX_CTL(l, qlm), rxx_ctl.u64);
  1945. /* Clear the completion flag and initiate a new request */
  1946. rxx_eer.u64 = csr_rd_node(node, CVMX_GSERX_BR_RXX_EER(l, qlm));
  1947. rxx_eer.s.rxt_esv = 0;
  1948. rxx_eer.s.rxt_eer = 1;
  1949. csr_wr_node(node, CVMX_GSERX_BR_RXX_EER(l, qlm), rxx_eer.u64);
  1950. pending |= 1 << l;
  1951. }
  1952. /*
  1953. * Wait for 250ms, approx 10x times measured value, as XFI/XLAUI
  1954. * can take 21-23ms, other interfaces can take 2-3ms.
  1955. */
  1956. timeout = get_timer(0);
  1957. lane_mask = 0;
  1958. while (pending) {
  1959. /* Wait for RX equalization to complete */
  1960. for (l = 0; l < max_lanes; l++) {
  1961. lane_mask = 1 << l;
  1962. /* Only check lanes that are pending */
  1963. if (!(pending & lane_mask))
  1964. continue;
  1965. /*
  1966. * Read the registers for checking Electrical Idle/CDR
  1967. * lock and the status of the RX equalization
  1968. */
  1969. eie_detsts.u64 = csr_rd_node(node, CVMX_GSERX_RX_EIE_DETSTS(qlm));
  1970. rxx_eer.u64 = csr_rd_node(node, CVMX_GSERX_BR_RXX_EER(l, qlm));
  1971. /*
  1972. * Mark failure if lane entered Electrical Idle or lost
  1973. * CDR Lock. The bit for the lane will have cleared in
  1974. * either EIESTS or CDRLOCK
  1975. */
  1976. if (!(eie_detsts.s.eiests & eie_detsts.s.cdrlock & lane_mask)) {
  1977. fail |= lane_mask;
  1978. pending &= ~lane_mask;
  1979. } else if (rxx_eer.s.rxt_esv) {
  1980. pending &= ~lane_mask;
  1981. }
  1982. }
  1983. /* Breakout of the loop on timeout */
  1984. if (get_timer(timeout) > 250)
  1985. break;
  1986. }
  1987. lane_mask = 0;
  1988. /* Cleanup and report status */
  1989. for (l = 0; l < max_lanes; l++) {
  1990. if (lane != -1 && lane != l)
  1991. continue;
  1992. lane_mask = 1 << l;
  1993. rxx_eer.u64 = csr_rd_node(node, CVMX_GSERX_BR_RXX_EER(l, qlm));
  1994. /* Switch back to hardware control */
  1995. rxx_ctl.u64 = csr_rd_node(node, CVMX_GSERX_BR_RXX_CTL(l, qlm));
  1996. rxx_ctl.s.rxt_swm = 0;
  1997. csr_wr_node(node, CVMX_GSERX_BR_RXX_CTL(l, qlm), rxx_ctl.u64);
  1998. /* Report status */
  1999. if (fail & lane_mask) {
  2000. #ifdef DEBUG_QLM
  2001. debug("%d:QLM%d: Lane%d RX equalization lost CDR Lock or entered Electrical Idle\n",
  2002. node, qlm, l);
  2003. #endif
  2004. } else if ((pending & lane_mask) || !rxx_eer.s.rxt_esv) {
  2005. #ifdef DEBUG_QLM
  2006. debug("%d:QLM%d: Lane %d RX equalization timeout\n", node, qlm, l);
  2007. #endif
  2008. fail |= 1 << l;
  2009. } else {
  2010. #ifdef DEBUG_QLM
  2011. char *dir_label[4] = { "Hold", "Inc", "Dec", "Hold" };
  2012. #ifdef DEBUG_QLM_RX
  2013. cvmx_gserx_lanex_rx_aeq_out_0_t rx_aeq_out_0;
  2014. cvmx_gserx_lanex_rx_aeq_out_1_t rx_aeq_out_1;
  2015. cvmx_gserx_lanex_rx_aeq_out_2_t rx_aeq_out_2;
  2016. cvmx_gserx_lanex_rx_vma_status_0_t rx_vma_status_0;
  2017. #endif
  2018. debug("%d:QLM%d: Lane%d: RX equalization completed.\n", node, qlm, l);
  2019. debug(" Tx Direction Hints TXPRE: %s, TXMAIN: %s, TXPOST: %s, Figure of Merit: %d\n",
  2020. dir_label[(rxx_eer.s.rxt_esm) & 0x3],
  2021. dir_label[((rxx_eer.s.rxt_esm) >> 2) & 0x3],
  2022. dir_label[((rxx_eer.s.rxt_esm) >> 4) & 0x3], rxx_eer.s.rxt_esm >> 6);
  2023. #ifdef DEBUG_QLM_RX
  2024. rx_aeq_out_0.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_RX_AEQ_OUT_0(l, qlm));
  2025. rx_aeq_out_1.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_RX_AEQ_OUT_1(l, qlm));
  2026. rx_aeq_out_2.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_RX_AEQ_OUT_2(l, qlm));
  2027. rx_vma_status_0.u64 =
  2028. csr_rd_node(node, CVMX_GSERX_LANEX_RX_VMA_STATUS_0(l, qlm));
  2029. debug(" DFE Tap1:%lu, Tap2:%ld, Tap3:%ld, Tap4:%ld, Tap5:%ld\n",
  2030. (unsigned int long)cvmx_bit_extract(rx_aeq_out_1.u64, 0, 5),
  2031. (unsigned int long)cvmx_bit_extract_smag(rx_aeq_out_1.u64, 5, 9),
  2032. (unsigned int long)cvmx_bit_extract_smag(rx_aeq_out_1.u64, 10, 14),
  2033. (unsigned int long)cvmx_bit_extract_smag(rx_aeq_out_0.u64, 0, 4),
  2034. (unsigned int long)cvmx_bit_extract_smag(rx_aeq_out_0.u64, 5, 9));
  2035. debug(" Pre-CTLE Gain:%lu, Post-CTLE Gain:%lu, CTLE Peak:%lu, CTLE Pole:%lu\n",
  2036. (unsigned int long)cvmx_bit_extract(rx_aeq_out_2.u64, 4, 4),
  2037. (unsigned int long)cvmx_bit_extract(rx_aeq_out_2.u64, 0, 4),
  2038. (unsigned int long)cvmx_bit_extract(rx_vma_status_0.u64, 2, 4),
  2039. (unsigned int long)cvmx_bit_extract(rx_vma_status_0.u64, 0, 2));
  2040. #endif
  2041. #endif
  2042. }
  2043. }
  2044. return (fail) ? -1 : 0;
  2045. }
  2046. /**
  2047. * Errata GSER-27882 -GSER 10GBASE-KR Transmit Equalizer
  2048. * Training may not update PHY Tx Taps. This function is not static
  2049. * so we can share it with BGX KR
  2050. *
  2051. * @param node Node to apply errata workaround
  2052. * @param qlm QLM to apply errata workaround
  2053. * @param lane Lane to apply the errata
  2054. */
  2055. int cvmx_qlm_gser_errata_27882(int node, int qlm, int lane)
  2056. {
  2057. cvmx_gserx_lanex_pcs_ctlifc_0_t clifc0;
  2058. cvmx_gserx_lanex_pcs_ctlifc_2_t clifc2;
  2059. if (!(OCTEON_IS_MODEL(OCTEON_CN73XX_PASS1_0) || OCTEON_IS_MODEL(OCTEON_CN73XX_PASS1_1) ||
  2060. OCTEON_IS_MODEL(OCTEON_CN73XX_PASS1_2) || OCTEON_IS_MODEL(OCTEON_CNF75XX_PASS1_0) ||
  2061. OCTEON_IS_MODEL(OCTEON_CN78XX)))
  2062. return 0;
  2063. if (CVMX_WAIT_FOR_FIELD64_NODE(node, CVMX_GSERX_RX_EIE_DETSTS(qlm),
  2064. cvmx_gserx_rx_eie_detsts_t, cdrlock, &,
  2065. (1 << lane), 200))
  2066. return -1;
  2067. clifc0.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_0(lane, qlm));
  2068. clifc0.s.cfg_tx_coeff_req_ovrrd_val = 1;
  2069. csr_wr_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_0(lane, qlm), clifc0.u64);
  2070. clifc2.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_2(lane, qlm));
  2071. clifc2.s.cfg_tx_coeff_req_ovrrd_en = 1;
  2072. csr_wr_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_2(lane, qlm), clifc2.u64);
  2073. clifc2.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_2(lane, qlm));
  2074. clifc2.s.ctlifc_ovrrd_req = 1;
  2075. csr_wr_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_2(lane, qlm), clifc2.u64);
  2076. clifc2.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_2(lane, qlm));
  2077. clifc2.s.cfg_tx_coeff_req_ovrrd_en = 0;
  2078. csr_wr_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_2(lane, qlm), clifc2.u64);
  2079. clifc2.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_2(lane, qlm));
  2080. clifc2.s.ctlifc_ovrrd_req = 1;
  2081. csr_wr_node(node, CVMX_GSERX_LANEX_PCS_CTLIFC_2(lane, qlm), clifc2.u64);
  2082. return 0;
  2083. }
  2084. /**
  2085. * Updates the RX EQ Default Settings Update (CTLE Bias) to support longer
  2086. * SERDES channels
  2087. *
  2088. * @INTERNAL
  2089. *
  2090. * @param node Node number to configure
  2091. * @param qlm QLM number to configure
  2092. */
  2093. void cvmx_qlm_gser_errata_25992(int node, int qlm)
  2094. {
  2095. int lane;
  2096. int num_lanes = cvmx_qlm_get_lanes(qlm);
  2097. if (!(OCTEON_IS_MODEL(OCTEON_CN73XX_PASS1_0) || OCTEON_IS_MODEL(OCTEON_CN73XX_PASS1_1) ||
  2098. OCTEON_IS_MODEL(OCTEON_CN73XX_PASS1_2) || OCTEON_IS_MODEL(OCTEON_CN78XX_PASS1_X)))
  2099. return;
  2100. for (lane = 0; lane < num_lanes; lane++) {
  2101. cvmx_gserx_lanex_rx_ctle_ctrl_t rx_ctle_ctrl;
  2102. cvmx_gserx_lanex_rx_cfg_4_t rx_cfg_4;
  2103. rx_ctle_ctrl.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_RX_CTLE_CTRL(lane, qlm));
  2104. rx_ctle_ctrl.s.pcs_sds_rx_ctle_bias_ctrl = 3;
  2105. csr_wr_node(node, CVMX_GSERX_LANEX_RX_CTLE_CTRL(lane, qlm), rx_ctle_ctrl.u64);
  2106. rx_cfg_4.u64 = csr_rd_node(node, CVMX_GSERX_LANEX_RX_CFG_4(lane, qlm));
  2107. rx_cfg_4.s.cfg_rx_errdet_ctrl = 0xcd6f;
  2108. csr_wr_node(node, CVMX_GSERX_LANEX_RX_CFG_4(lane, qlm), rx_cfg_4.u64);
  2109. }
  2110. }
  2111. void cvmx_qlm_display_registers(int qlm)
  2112. {
  2113. int num_lanes = cvmx_qlm_get_lanes(qlm);
  2114. int lane;
  2115. const __cvmx_qlm_jtag_field_t *ptr = cvmx_qlm_jtag_get_field();
  2116. debug("%29s", "Field[<stop bit>:<start bit>]");
  2117. for (lane = 0; lane < num_lanes; lane++)
  2118. debug("\t Lane %d", lane);
  2119. debug("\n");
  2120. while (ptr && ptr->name) {
  2121. debug("%20s[%3d:%3d]", ptr->name, ptr->stop_bit, ptr->start_bit);
  2122. for (lane = 0; lane < num_lanes; lane++) {
  2123. u64 val;
  2124. int tx_byp = 0;
  2125. /*
  2126. * Make sure serdes_tx_byp is set for displaying
  2127. * TX amplitude and TX demphasis field values.
  2128. */
  2129. if (strncmp(ptr->name, "biasdrv_", 8) == 0 ||
  2130. strncmp(ptr->name, "tcoeff_", 7) == 0) {
  2131. tx_byp = cvmx_qlm_jtag_get(qlm, lane, "serdes_tx_byp");
  2132. if (tx_byp == 0) {
  2133. debug("\t \t");
  2134. continue;
  2135. }
  2136. }
  2137. val = cvmx_qlm_jtag_get(qlm, lane, ptr->name);
  2138. debug("\t%4llu (0x%04llx)", (unsigned long long)val,
  2139. (unsigned long long)val);
  2140. }
  2141. debug("\n");
  2142. ptr++;
  2143. }
  2144. }
  2145. /* ToDo: CVMX_DUMP_GSER removed for now (unused!) */