siutils.c 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819
  1. /*
  2. * Misc utility routines for accessing chip-specific features
  3. * of the SiliconBackplane-based Broadcom chips.
  4. *
  5. * Portions of this code are copyright (c) 2020 Cypress Semiconductor Corporation
  6. *
  7. * Copyright (C) 1999-2020, Broadcom Corporation
  8. *
  9. * Unless you and Broadcom execute a separate written software license
  10. * agreement governing use of this software, this software is licensed to you
  11. * under the terms of the GNU General Public License version 2 (the "GPL"),
  12. * available at http://www.broadcom.com/licenses/GPLv2.php, with the
  13. * following added to such license:
  14. *
  15. * As a special exception, the copyright holders of this software give you
  16. * permission to link this software with independent modules, and to copy and
  17. * distribute the resulting executable under terms of your choice, provided that
  18. * you also meet, for each linked independent module, the terms and conditions of
  19. * the license of that module. An independent module is a module which is not
  20. * derived from this software. The special exception does not apply to any
  21. * modifications of the software.
  22. *
  23. * Notwithstanding the above, under no circumstances may you combine this
  24. * software in any way with any other Broadcom software provided under a license
  25. * other than the GPL, without Broadcom's express prior written consent.
  26. *
  27. *
  28. * <<Broadcom-WL-IPTag/Open:>>
  29. *
  30. * $Id: siutils.c 701025 2017-05-23 10:23:52Z $
  31. */
  32. #include <bcm_cfg.h>
  33. #include <typedefs.h>
  34. #include <bcmdefs.h>
  35. #include <osl.h>
  36. #include <bcmutils.h>
  37. #include <siutils.h>
  38. #include <bcmdevs.h>
  39. #include <hndsoc.h>
  40. #include <sbchipc.h>
  41. #include <sbgci.h>
  42. #ifndef BCMSDIO
  43. #include <pcie_core.h>
  44. #endif // endif
  45. #ifdef BCMPCIEDEV
  46. #include <pciedev.h>
  47. #endif /* BCMPCIEDEV */
  48. #include <pcicfg.h>
  49. #include <sbpcmcia.h>
  50. #include <sbsysmem.h>
  51. #include <sbsocram.h>
  52. #ifdef BCMSDIO
  53. #include <bcmsdh.h>
  54. #include <sdio.h>
  55. #include <sbsdio.h>
  56. #include <sbhnddma.h>
  57. #include <sbsdpcmdev.h>
  58. #include <bcmsdpcm.h>
  59. #endif /* BCMSDIO */
  60. #include <hndpmu.h>
  61. #ifdef BCMSPI
  62. #include <spid.h>
  63. #endif /* BCMSPI */
  64. #ifdef BCM_SDRBL
  65. #include <hndcpu.h>
  66. #endif /* BCM_SDRBL */
  67. #ifdef HNDGCI
  68. #include <hndgci.h>
  69. #endif /* HNDGCI */
  70. #ifdef WLGCIMBHLR
  71. #include <hnd_gci.h>
  72. #endif /* WLGCIMBHLR */
  73. #ifdef BCMULP
  74. #include <ulp.h>
  75. #endif /* BCMULP */
  76. #include <hndlhl.h>
  77. #include <lpflags.h>
  78. #include "siutils_priv.h"
  79. #ifdef SECI_UART
  80. /* Defines the set of GPIOs to be used for SECI UART if not specified in NVRAM */
  81. /* For further details on each ppin functionality please refer to PINMUX table in
  82. * Top level architecture of BCMXXXX Chip
  83. */
  84. #define DEFAULT_SECI_UART_PINMUX 0x08090a0b
  85. #define DEFAULT_SECI_UART_PINMUX_43430 0x0102
  86. static bool force_seci_clk = 0;
  87. #endif /* SECI_UART */
  88. #define XTAL_FREQ_26000KHZ 26000
  89. /**
  90. * A set of PMU registers is clocked in the ILP domain, which has an implication on register write
  91. * behavior: if such a register is written, it takes multiple ILP clocks for the PMU block to absorb
  92. * the write. During that time the 'SlowWritePending' bit in the PMUStatus register is set.
  93. */
  94. #define PMUREGS_ILP_SENSITIVE(regoff) \
  95. ((regoff) == OFFSETOF(pmuregs_t, pmutimer) || \
  96. (regoff) == OFFSETOF(pmuregs_t, pmuwatchdog) || \
  97. (regoff) == OFFSETOF(pmuregs_t, res_req_timer))
  98. #define CHIPCREGS_ILP_SENSITIVE(regoff) \
  99. ((regoff) == OFFSETOF(chipcregs_t, pmutimer) || \
  100. (regoff) == OFFSETOF(chipcregs_t, pmuwatchdog) || \
  101. (regoff) == OFFSETOF(chipcregs_t, res_req_timer))
  102. #define GCI_FEM_CTRL_WAR 0x11111111
  103. #ifndef AXI_TO_VAL
  104. #define AXI_TO_VAL 19
  105. #endif /* AXI_TO_VAL */
  106. #ifndef AXI_TO_VAL_4347
  107. /*
  108. * Increase BP timeout for fast clock and short PCIe timeouts
  109. * New timeout: 2 ** 25 cycles
  110. */
  111. #define AXI_TO_VAL_4347 25
  112. #endif /* AXI_TO_VAL_4347 */
  113. /* local prototypes */
  114. static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
  115. uint bustype, void *sdh, char **vars, uint *varsz);
  116. static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh);
  117. static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
  118. uint *origidx, volatile void *regs);
  119. static bool si_pmu_is_ilp_sensitive(uint32 idx, uint regoff);
  120. /* global variable to indicate reservation/release of gpio's */
  121. static uint32 si_gpioreservation = 0;
  122. /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
  123. static bool si_onetimeinit = FALSE;
  124. #ifdef SR_DEBUG
  125. static const uint32 si_power_island_test_array[] = {
  126. 0x0000, 0x0001, 0x0010, 0x0011,
  127. 0x0100, 0x0101, 0x0110, 0x0111,
  128. 0x1000, 0x1001, 0x1010, 0x1011,
  129. 0x1100, 0x1101, 0x1110, 0x1111
  130. };
  131. #endif /* SR_DEBUG */
  132. int do_4360_pcie2_war = 0;
  133. #ifdef BCMULP
  134. /* Variable to store boot_type: warm_boot/cold_boot/etc. */
  135. static int boot_type = 0;
  136. #endif // endif
  137. /* global kernel resource */
  138. static si_info_t ksii;
  139. static si_cores_info_t ksii_cores_info;
  140. /**
  141. * Allocate an si handle. This function may be called multiple times.
  142. *
  143. * devid - pci device id (used to determine chip#)
  144. * osh - opaque OS handle
  145. * regs - virtual address of initial core registers
  146. * bustype - pci/pcmcia/sb/sdio/etc
  147. * vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
  148. * function set 'vars' to NULL, making dereferencing of this parameter undesired.
  149. * varsz - pointer to int to return the size of the vars
  150. */
  151. si_t *
  152. si_attach(uint devid, osl_t *osh, volatile void *regs,
  153. uint bustype, void *sdh, char **vars, uint *varsz)
  154. {
  155. si_info_t *sii;
  156. si_cores_info_t *cores_info;
  157. /* alloc si_info_t */
  158. /* freed after ucode download for firmware builds */
  159. if ((sii = MALLOCZ_NOPERSIST(osh, sizeof(si_info_t))) == NULL) {
  160. SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
  161. return (NULL);
  162. }
  163. /* alloc si_cores_info_t */
  164. if ((cores_info = (si_cores_info_t *)MALLOCZ(osh,
  165. sizeof(si_cores_info_t))) == NULL) {
  166. SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
  167. MFREE(osh, sii, sizeof(si_info_t));
  168. return (NULL);
  169. }
  170. sii->cores_info = cores_info;
  171. if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) {
  172. MFREE(osh, sii, sizeof(si_info_t));
  173. MFREE(osh, cores_info, sizeof(si_cores_info_t));
  174. return (NULL);
  175. }
  176. sii->vars = vars ? *vars : NULL;
  177. sii->varsz = varsz ? *varsz : 0;
  178. return (si_t *)sii;
  179. }
  180. static uint32 wd_msticks; /**< watchdog timer ticks normalized to ms */
  181. /** Returns the backplane address of the chipcommon core for a particular chip */
  182. uint32
  183. si_enum_base(uint devid)
  184. {
  185. // NIC/DHD build
  186. switch (devid) {
  187. case BCM7271_CHIP_ID:
  188. case BCM7271_D11AC_ID:
  189. case BCM7271_D11AC2G_ID:
  190. case BCM7271_D11AC5G_ID:
  191. return 0xF1800000;
  192. }
  193. return SI_ENUM_BASE_DEFAULT;
  194. }
  195. /** generic kernel variant of si_attach(). Is not called for Linux WLAN NIC builds. */
  196. si_t *
  197. si_kattach(osl_t *osh)
  198. {
  199. static bool ksii_attached = FALSE;
  200. si_cores_info_t *cores_info;
  201. if (!ksii_attached) {
  202. void *regs = NULL;
  203. const uint device_id = BCM4710_DEVICE_ID; // pick an arbitrary default device_id
  204. regs = REG_MAP(si_enum_base(device_id), SI_CORE_SIZE); // map physical to virtual
  205. cores_info = (si_cores_info_t *)&ksii_cores_info;
  206. ksii.cores_info = cores_info;
  207. ASSERT(osh);
  208. if (si_doattach(&ksii, device_id, osh, regs,
  209. SI_BUS, NULL,
  210. osh != SI_OSH ? &(ksii.vars) : NULL,
  211. osh != SI_OSH ? &(ksii.varsz) : NULL) == NULL) {
  212. SI_ERROR(("si_kattach: si_doattach failed\n"));
  213. REG_UNMAP(regs);
  214. return NULL;
  215. }
  216. REG_UNMAP(regs);
  217. /* save ticks normalized to ms for si_watchdog_ms() */
  218. if (PMUCTL_ENAB(&ksii.pub)) {
  219. /* based on 32KHz ILP clock */
  220. wd_msticks = 32;
  221. } else {
  222. wd_msticks = ALP_CLOCK / 1000;
  223. }
  224. ksii_attached = TRUE;
  225. SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
  226. CCREV(ksii.pub.ccrev), wd_msticks));
  227. }
  228. return &ksii.pub;
  229. }
  230. static bool
  231. si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh)
  232. {
  233. BCM_REFERENCE(sdh);
  234. BCM_REFERENCE(devid);
  235. /* need to set memseg flag for CF card first before any sb registers access */
  236. if (BUSTYPE(bustype) == PCMCIA_BUS)
  237. sii->memseg = TRUE;
  238. #if defined(BCMSDIO) && !defined(BCMSDIOLITE)
  239. if (BUSTYPE(bustype) == SDIO_BUS) {
  240. int err;
  241. uint8 clkset;
  242. /* Try forcing SDIO core to do ALPAvail request only */
  243. clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
  244. bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
  245. if (!err) {
  246. uint8 clkval;
  247. /* If register supported, wait for ALPAvail and then force ALP */
  248. clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL);
  249. if ((clkval & ~SBSDIO_AVBITS) == clkset) {
  250. SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
  251. SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)),
  252. PMU_MAX_TRANSITION_DLY);
  253. if (!SBSDIO_ALPAV(clkval)) {
  254. SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n",
  255. clkval));
  256. return FALSE;
  257. }
  258. clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
  259. bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
  260. clkset, &err);
  261. OSL_DELAY(65);
  262. }
  263. }
  264. /* Also, disable the extra SDIO pull-ups */
  265. bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
  266. }
  267. #ifdef BCMSPI
  268. /* Avoid backplane accesses before wake-wlan (i.e. htavail) for spi.
  269. * F1 read accesses may return correct data but with data-not-available dstatus bit set.
  270. */
  271. if (BUSTYPE(bustype) == SPI_BUS) {
  272. int err;
  273. uint32 regdata;
  274. /* wake up wlan function :WAKE_UP goes as HT_AVAIL request in hardware */
  275. regdata = bcmsdh_cfg_read_word(sdh, SDIO_FUNC_0, SPID_CONFIG, NULL);
  276. SI_MSG(("F0 REG0 rd = 0x%x\n", regdata));
  277. regdata |= WAKE_UP;
  278. bcmsdh_cfg_write_word(sdh, SDIO_FUNC_0, SPID_CONFIG, regdata, &err);
  279. OSL_DELAY(100000);
  280. }
  281. #endif /* BCMSPI */
  282. #endif /* BCMSDIO && BCMDONGLEHOST && !BCMSDIOLITE */
  283. return TRUE;
  284. }
  285. uint32
  286. si_get_pmu_reg_addr(si_t *sih, uint32 offset)
  287. {
  288. si_info_t *sii = SI_INFO(sih);
  289. uint32 pmuaddr = INVALID_ADDR;
  290. uint origidx = 0;
  291. SI_MSG(("%s: pmu access, offset: %x\n", __FUNCTION__, offset));
  292. if (!(sii->pub.cccaps & CC_CAP_PMU)) {
  293. goto done;
  294. }
  295. if (AOB_ENAB(&sii->pub)) {
  296. uint pmucoreidx;
  297. pmuregs_t *pmu;
  298. SI_MSG(("%s: AOBENAB: %x\n", __FUNCTION__, offset));
  299. origidx = sii->curidx;
  300. pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
  301. pmu = si_setcoreidx(&sii->pub, pmucoreidx);
  302. pmuaddr = (uint32)(uintptr)((volatile uint8*)pmu + offset);
  303. si_setcoreidx(sih, origidx);
  304. } else
  305. pmuaddr = SI_ENUM_BASE(sih) + offset;
  306. done:
  307. printf("%s: addrRET: %x\n", __FUNCTION__, pmuaddr);
  308. return pmuaddr;
  309. }
  310. static bool
  311. si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
  312. uint *origidx, volatile void *regs)
  313. {
  314. si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
  315. bool pci, pcie, pcie_gen2 = FALSE;
  316. uint i;
  317. uint pciidx, pcieidx, pcirev, pcierev;
  318. #if defined(BCM_BACKPLANE_TIMEOUT) || defined(AXI_TIMEOUTS)
  319. /* first, enable backplane timeouts */
  320. si_slave_wrapper_add(&sii->pub);
  321. #endif // endif
  322. sii->curidx = 0;
  323. cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
  324. ASSERT((uintptr)cc);
  325. /* get chipcommon rev */
  326. sii->pub.ccrev = (int)si_corerev(&sii->pub);
  327. /* get chipcommon chipstatus */
  328. if (CCREV(sii->pub.ccrev) >= 11)
  329. sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
  330. /* get chipcommon capabilites */
  331. sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
  332. /* get chipcommon extended capabilities */
  333. if (CCREV(sii->pub.ccrev) >= 35)
  334. sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
  335. /* get pmu rev and caps */
  336. if (sii->pub.cccaps & CC_CAP_PMU) {
  337. if (AOB_ENAB(&sii->pub)) {
  338. uint pmucoreidx;
  339. pmuregs_t *pmu;
  340. struct si_pub *sih = &sii->pub;
  341. pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
  342. if (!GOODIDX(pmucoreidx)) {
  343. SI_ERROR(("si_buscore_setup: si_findcoreidx failed\n"));
  344. return FALSE;
  345. }
  346. pmu = si_setcoreidx(&sii->pub, pmucoreidx);
  347. sii->pub.pmucaps = R_REG(sii->osh, &pmu->pmucapabilities);
  348. si_setcoreidx(&sii->pub, SI_CC_IDX);
  349. sii->pub.gcirev = si_corereg(sih,
  350. GCI_CORE_IDX(sih),
  351. GCI_OFFSETOF(sih, gci_corecaps0), 0, 0) & GCI_CAP0_REV_MASK;
  352. } else
  353. sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
  354. sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
  355. }
  356. SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
  357. CCREV(sii->pub.ccrev), sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
  358. sii->pub.pmucaps));
  359. /* figure out bus/orignal core idx */
  360. sii->pub.buscoretype = NODEV_CORE_ID;
  361. sii->pub.buscorerev = (uint)NOREV;
  362. sii->pub.buscoreidx = BADIDX;
  363. pci = pcie = FALSE;
  364. pcirev = pcierev = (uint)NOREV;
  365. pciidx = pcieidx = BADIDX;
  366. for (i = 0; i < sii->numcores; i++) {
  367. uint cid, crev;
  368. si_setcoreidx(&sii->pub, i);
  369. cid = si_coreid(&sii->pub);
  370. crev = si_corerev(&sii->pub);
  371. /* Display cores found */
  372. SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x size:%x regs 0x%p\n",
  373. i, cid, crev, sii->coresba[i], sii->coresba_size[i],
  374. OSL_OBFUSCATE_BUF(sii->regs[i])));
  375. if (BUSTYPE(bustype) == SI_BUS) {
  376. /* now look at the chipstatus register to figure the pacakge */
  377. /* for SDIO but downloaded on PCIE dev */
  378. #ifdef BCMPCIEDEV_ENABLED
  379. if (cid == PCIE2_CORE_ID) {
  380. pcieidx = i;
  381. pcierev = crev;
  382. pcie = TRUE;
  383. pcie_gen2 = TRUE;
  384. }
  385. #endif // endif
  386. } else if (BUSTYPE(bustype) == PCI_BUS) {
  387. if (cid == PCI_CORE_ID) {
  388. pciidx = i;
  389. pcirev = crev;
  390. pci = TRUE;
  391. } else if ((cid == PCIE_CORE_ID) || (cid == PCIE2_CORE_ID)) {
  392. pcieidx = i;
  393. pcierev = crev;
  394. pcie = TRUE;
  395. if (cid == PCIE2_CORE_ID)
  396. pcie_gen2 = TRUE;
  397. }
  398. } else if ((BUSTYPE(bustype) == PCMCIA_BUS) &&
  399. (cid == PCMCIA_CORE_ID)) {
  400. sii->pub.buscorerev = crev;
  401. sii->pub.buscoretype = cid;
  402. sii->pub.buscoreidx = i;
  403. }
  404. #ifdef BCMSDIO
  405. else if (((BUSTYPE(bustype) == SDIO_BUS) ||
  406. (BUSTYPE(bustype) == SPI_BUS)) &&
  407. ((cid == PCMCIA_CORE_ID) ||
  408. (cid == SDIOD_CORE_ID))) {
  409. sii->pub.buscorerev = crev;
  410. sii->pub.buscoretype = cid;
  411. sii->pub.buscoreidx = i;
  412. }
  413. #endif /* BCMSDIO */
  414. /* find the core idx before entering this func. */
  415. if ((savewin && (savewin == cores_info->coresba[i])) ||
  416. (regs == cores_info->regs[i]))
  417. *origidx = i;
  418. }
  419. #if defined(PCIE_FULL_DONGLE)
  420. if (pcie) {
  421. if (pcie_gen2)
  422. sii->pub.buscoretype = PCIE2_CORE_ID;
  423. else
  424. sii->pub.buscoretype = PCIE_CORE_ID;
  425. sii->pub.buscorerev = pcierev;
  426. sii->pub.buscoreidx = pcieidx;
  427. }
  428. BCM_REFERENCE(pci);
  429. BCM_REFERENCE(pcirev);
  430. BCM_REFERENCE(pciidx);
  431. #else
  432. if (pci) {
  433. sii->pub.buscoretype = PCI_CORE_ID;
  434. sii->pub.buscorerev = pcirev;
  435. sii->pub.buscoreidx = pciidx;
  436. } else if (pcie) {
  437. if (pcie_gen2)
  438. sii->pub.buscoretype = PCIE2_CORE_ID;
  439. else
  440. sii->pub.buscoretype = PCIE_CORE_ID;
  441. sii->pub.buscorerev = pcierev;
  442. sii->pub.buscoreidx = pcieidx;
  443. }
  444. #endif /* defined(PCIE_FULL_DONGLE) */
  445. SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype,
  446. sii->pub.buscorerev));
  447. #if defined(BCMSDIO)
  448. /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was
  449. * already running.
  450. */
  451. if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) {
  452. if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) ||
  453. si_setcore(&sii->pub, ARMCM3_CORE_ID, 0))
  454. si_core_disable(&sii->pub, 0);
  455. }
  456. #endif /* BCMSDIO && BCMDONGLEHOST */
  457. /* return to the original core */
  458. si_setcoreidx(&sii->pub, *origidx);
  459. return TRUE;
  460. }
  461. uint16
  462. si_chipid(si_t *sih)
  463. {
  464. si_info_t *sii = SI_INFO(sih);
  465. return (sii->chipnew) ? sii->chipnew : sih->chip;
  466. }
  467. /* CHIP_ID's being mapped here should not be used anywhere else in the code */
  468. static void
  469. si_chipid_fixup(si_t *sih)
  470. {
  471. si_info_t *sii = SI_INFO(sih);
  472. ASSERT(sii->chipnew == 0);
  473. switch (sih->chip) {
  474. case BCM43567_CHIP_ID:
  475. sii->chipnew = sih->chip; /* save it */
  476. sii->pub.chip = BCM43570_CHIP_ID; /* chip class */
  477. break;
  478. case BCM43562_CHIP_ID:
  479. case BCM4358_CHIP_ID:
  480. case BCM43566_CHIP_ID:
  481. sii->chipnew = sih->chip; /* save it */
  482. sii->pub.chip = BCM43569_CHIP_ID; /* chip class */
  483. break;
  484. case BCM4356_CHIP_ID:
  485. case BCM4371_CHIP_ID:
  486. sii->chipnew = sih->chip; /* save it */
  487. sii->pub.chip = BCM4354_CHIP_ID; /* chip class */
  488. break;
  489. case BCM4357_CHIP_ID:
  490. case BCM4361_CHIP_ID:
  491. sii->chipnew = sih->chip; /* save it */
  492. sii->pub.chip = BCM4347_CHIP_ID; /* chip class */
  493. break;
  494. #ifdef CHIPS_CUSTOMER_HW6
  495. case BCM4377_CHIP_ID:
  496. sii->chipnew = sih->chip; /* save it */
  497. sii->pub.chip = BCM4369_CHIP_ID; /* chip class */
  498. break;
  499. #endif /* CHIPS_CUSTOMER_HW6 */
  500. default:
  501. break;
  502. }
  503. }
  504. #ifdef BCMULP
  505. static void
  506. si_check_boot_type(si_t *sih, osl_t *osh)
  507. {
  508. if (sih->pmurev >= 30) {
  509. boot_type = PMU_REG_NEW(sih, swscratch, 0, 0);
  510. } else {
  511. boot_type = CHIPC_REG(sih, flashdata, 0, 0);
  512. }
  513. SI_ERROR(("%s: boot_type: 0x%08x\n", __func__, boot_type));
  514. }
  515. #endif /* BCMULP */
  516. #ifdef BCM_BACKPLANE_TIMEOUT
  517. uint32
  518. si_clear_backplane_to_fast(void *sih, void *addr)
  519. {
  520. si_t *_sih = DISCARD_QUAL(sih, si_t);
  521. if (CHIPTYPE(_sih->socitype) == SOCI_AI) {
  522. return ai_clear_backplane_to_fast(_sih, addr);
  523. }
  524. return 0;
  525. }
  526. const si_axi_error_info_t *
  527. si_get_axi_errlog_info(si_t *sih)
  528. {
  529. if (CHIPTYPE(sih->socitype) == SOCI_AI) {
  530. return (const si_axi_error_info_t *)sih->err_info;
  531. }
  532. return NULL;
  533. }
  534. void
  535. si_reset_axi_errlog_info(si_t *sih)
  536. {
  537. if (sih->err_info) {
  538. sih->err_info->count = 0;
  539. }
  540. }
  541. #endif /* BCM_BACKPLANE_TIMEOUT */
  542. /**
  543. * Allocate an si handle. This function may be called multiple times. This function is called by
  544. * both si_attach() and si_kattach().
  545. *
  546. * vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
  547. * function set 'vars' to NULL.
  548. */
  549. static si_info_t *
  550. si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
  551. uint bustype, void *sdh, char **vars, uint *varsz)
  552. {
  553. struct si_pub *sih = &sii->pub;
  554. uint32 w, savewin;
  555. chipcregs_t *cc;
  556. char *pvars = NULL;
  557. uint origidx;
  558. #ifdef NVSRCX
  559. char *sromvars;
  560. #endif // endif
  561. ASSERT(GOODREGS(regs));
  562. savewin = 0;
  563. sih->buscoreidx = BADIDX;
  564. sii->device_removed = FALSE;
  565. sii->curmap = regs;
  566. sii->sdh = sdh;
  567. sii->osh = osh;
  568. sii->second_bar0win = ~0x0;
  569. sih->enum_base = si_enum_base(devid);
  570. #if defined(BCM_BACKPLANE_TIMEOUT)
  571. sih->err_info = MALLOCZ(osh, sizeof(si_axi_error_info_t));
  572. if (sih->err_info == NULL) {
  573. SI_ERROR(("%s: %zu bytes MALLOC FAILED",
  574. __FUNCTION__, sizeof(si_axi_error_info_t)));
  575. }
  576. #endif /* BCM_BACKPLANE_TIMEOUT */
  577. #if defined(BCM_BACKPLANE_TIMEOUT)
  578. osl_set_bpt_cb(osh, (void *)si_clear_backplane_to_fast, (void *)sih);
  579. #endif // endif
  580. /* check to see if we are a si core mimic'ing a pci core */
  581. if ((bustype == PCI_BUS) &&
  582. (OSL_PCI_READ_CONFIG(sii->osh, PCI_SPROM_CONTROL, sizeof(uint32)) == 0xffffffff)) {
  583. SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI "
  584. "devid:0x%x\n", __FUNCTION__, devid));
  585. bustype = SI_BUS;
  586. }
  587. /* find Chipcommon address */
  588. if (bustype == PCI_BUS) {
  589. savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
  590. if (!GOODCOREADDR(savewin, SI_ENUM_BASE(sih)))
  591. savewin = SI_ENUM_BASE(sih);
  592. OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE(sih));
  593. if (!regs)
  594. return NULL;
  595. cc = (chipcregs_t *)regs;
  596. #ifdef BCMSDIO
  597. } else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
  598. cc = (chipcregs_t *)sii->curmap;
  599. #endif // endif
  600. } else {
  601. cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE(sih), SI_CORE_SIZE);
  602. }
  603. sih->bustype = bustype;
  604. #ifdef BCMBUSTYPE
  605. if (bustype != BUSTYPE(bustype)) {
  606. SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
  607. bustype, BUSTYPE(bustype)));
  608. return NULL;
  609. }
  610. #endif // endif
  611. /* bus/core/clk setup for register access */
  612. if (!si_buscore_prep(sii, bustype, devid, sdh)) {
  613. SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype));
  614. return NULL;
  615. }
  616. /* ChipID recognition.
  617. * We assume we can read chipid at offset 0 from the regs arg.
  618. * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
  619. * some way of recognizing them needs to be added here.
  620. */
  621. if (!cc) {
  622. SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__));
  623. return NULL;
  624. }
  625. w = R_REG(osh, &cc->chipid);
  626. if ((w & 0xfffff) == 148277) w -= 65532;
  627. sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
  628. /* Might as wll fill in chip id rev & pkg */
  629. sih->chip = w & CID_ID_MASK;
  630. sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
  631. sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
  632. si_chipid_fixup(sih);
  633. if (CHIPID(sih->chip) == BCM43465_CHIP_ID) {
  634. sih->chip = BCM4366_CHIP_ID;
  635. } else if (CHIPID(sih->chip) == BCM43525_CHIP_ID) {
  636. sih->chip = BCM4365_CHIP_ID;
  637. }
  638. sih->issim = IS_SIM(sih->chippkg);
  639. #ifdef CHIPS_CUSTOMER_HW6
  640. if (MULTIBP_CAP(sih))
  641. {
  642. sih->_multibp_enable = TRUE;
  643. }
  644. #endif // endif
  645. /* scan for cores */
  646. if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) {
  647. SI_MSG(("Found chip type SB (0x%08x)\n", w));
  648. sb_scan(&sii->pub, regs, devid);
  649. } else if ((CHIPTYPE(sii->pub.socitype) == SOCI_AI) ||
  650. (CHIPTYPE(sii->pub.socitype) == SOCI_NAI) ||
  651. (CHIPTYPE(sii->pub.socitype) == SOCI_DVTBUS)) {
  652. if (CHIPTYPE(sii->pub.socitype) == SOCI_AI)
  653. SI_MSG(("Found chip type AI (0x%08x)\n", w));
  654. else if (CHIPTYPE(sii->pub.socitype) == SOCI_NAI)
  655. SI_MSG(("Found chip type NAI (0x%08x)\n", w));
  656. else
  657. SI_MSG(("Found chip type DVT (0x%08x)\n", w));
  658. /* pass chipc address instead of original core base */
  659. if (sii->osh) {
  660. sii->axi_wrapper = (axi_wrapper_t *)MALLOCZ(sii->osh,
  661. (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS));
  662. if (sii->axi_wrapper == NULL) {
  663. SI_ERROR(("%s: %zu bytes MALLOC Failed", __FUNCTION__,
  664. (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS)));
  665. }
  666. } else {
  667. sii->axi_wrapper = NULL;
  668. }
  669. ai_scan(&sii->pub, (void *)(uintptr)cc, devid);
  670. } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) {
  671. SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip));
  672. /* pass chipc address instead of original core base */
  673. ub_scan(&sii->pub, (void *)(uintptr)cc, devid);
  674. } else {
  675. SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
  676. return NULL;
  677. }
  678. /* no cores found, bail out */
  679. if (sii->numcores == 0) {
  680. SI_ERROR(("si_doattach: could not find any cores\n"));
  681. return NULL;
  682. }
  683. /* bus/core/clk setup */
  684. origidx = SI_CC_IDX;
  685. if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
  686. SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
  687. goto exit;
  688. }
  689. #ifdef BCMULP
  690. if (BCMULP_ENAB()) {
  691. si_check_boot_type(sih, osh);
  692. if (ulp_module_init(osh, sih) != BCME_OK) {
  693. ULP_ERR(("%s: err in ulp_module_init\n", __FUNCTION__));
  694. goto exit;
  695. }
  696. }
  697. #endif /* BCMULP */
  698. #if !defined(_CFEZ_) || defined(CFG_WL)
  699. /* assume current core is CC */
  700. if ((CCREV(sii->pub.ccrev) == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID ||
  701. CHIPID(sih->chip) == BCM43235_CHIP_ID ||
  702. CHIPID(sih->chip) == BCM43234_CHIP_ID ||
  703. CHIPID(sih->chip) == BCM43238_CHIP_ID) &&
  704. (CHIPREV(sii->pub.chiprev) <= 2))) {
  705. if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
  706. uint clkdiv;
  707. clkdiv = R_REG(osh, &cc->clkdiv);
  708. /* otp_clk_div is even number, 120/14 < 9mhz */
  709. clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
  710. W_REG(osh, &cc->clkdiv, clkdiv);
  711. SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv));
  712. }
  713. OSL_DELAY(10);
  714. }
  715. /* Set the clkdiv2 divisor bits (2:0) to 0x4 if srom is present */
  716. if (bustype == SI_BUS) {
  717. uint32 clkdiv2, sromprsnt, capabilities, srom_supported;
  718. capabilities = R_REG(osh, &cc->capabilities);
  719. srom_supported = capabilities & SROM_SUPPORTED;
  720. if (srom_supported)
  721. {
  722. sromprsnt = R_REG(osh, &cc->sromcontrol);
  723. sromprsnt = sromprsnt & SROM_PRSNT_MASK;
  724. if (sromprsnt) {
  725. /* SROM clock come from backplane clock/div2. Must <= 1Mhz */
  726. clkdiv2 = (R_REG(osh, &cc->clkdiv2) & ~CLKD2_SROM);
  727. clkdiv2 |= CLKD2_SROMDIV_192;
  728. W_REG(osh, &cc->clkdiv2, clkdiv2);
  729. }
  730. }
  731. }
  732. if (bustype == PCI_BUS) {
  733. }
  734. #endif // endif
  735. #ifdef BCM_SDRBL
  736. /* 4360 rom bootloader in PCIE case, if the SDR is enabled, But preotection is
  737. * not turned on, then we want to hold arm in reset.
  738. * Bottomline: In sdrenable case, we allow arm to boot only when protection is
  739. * turned on.
  740. */
  741. if (CHIP_HOSTIF_PCIE(&(sii->pub))) {
  742. uint32 sflags = si_arm_sflags(&(sii->pub));
  743. /* If SDR is enabled but protection is not turned on
  744. * then we want to force arm to WFI.
  745. */
  746. if ((sflags & (SISF_SDRENABLE | SISF_TCMPROT)) == SISF_SDRENABLE) {
  747. disable_arm_irq();
  748. while (1) {
  749. hnd_cpu_wait(sih);
  750. }
  751. }
  752. }
  753. #endif /* BCM_SDRBL */
  754. pvars = NULL;
  755. BCM_REFERENCE(pvars);
  756. {
  757. sii->lhl_ps_mode = LHL_PS_MODE_0;
  758. }
  759. if (!si_onetimeinit) {
  760. if (CCREV(sii->pub.ccrev) >= 20) {
  761. uint32 gpiopullup = 0, gpiopulldown = 0;
  762. cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
  763. ASSERT(cc != NULL);
  764. W_REG(osh, &cc->gpiopullup, gpiopullup);
  765. W_REG(osh, &cc->gpiopulldown, gpiopulldown);
  766. si_setcoreidx(sih, origidx);
  767. }
  768. }
  769. /* clear any previous epidiag-induced target abort */
  770. ASSERT(!si_taclear(sih, FALSE));
  771. #if defined(BCMPMU_STATS) && !defined(BCMPMU_STATS_DISABLED)
  772. si_pmustatstimer_init(sih);
  773. #endif /* BCMPMU_STATS */
  774. #ifdef BOOTLOADER_CONSOLE_OUTPUT
  775. /* Enable console prints */
  776. si_muxenab(sii, 3);
  777. #endif // endif
  778. return (sii);
  779. exit:
  780. return NULL;
  781. }
  782. /** may be called with core in reset */
  783. void
  784. si_detach(si_t *sih)
  785. {
  786. si_info_t *sii = SI_INFO(sih);
  787. si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
  788. uint idx;
  789. if (BUSTYPE(sih->bustype) == SI_BUS)
  790. for (idx = 0; idx < SI_MAXCORES; idx++)
  791. if (cores_info->regs[idx]) {
  792. REG_UNMAP(cores_info->regs[idx]);
  793. cores_info->regs[idx] = NULL;
  794. }
  795. #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
  796. if (cores_info != &ksii_cores_info)
  797. #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
  798. MFREE(sii->osh, cores_info, sizeof(si_cores_info_t));
  799. #if defined(BCM_BACKPLANE_TIMEOUT)
  800. if (sih->err_info) {
  801. MFREE(sii->osh, sih->err_info, sizeof(si_axi_error_info_t));
  802. sii->pub.err_info = NULL;
  803. }
  804. #endif /* BCM_BACKPLANE_TIMEOUT */
  805. if (sii->axi_wrapper) {
  806. MFREE(sii->osh, sii->axi_wrapper,
  807. (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS));
  808. sii->axi_wrapper = NULL;
  809. }
  810. #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
  811. if (sii != &ksii)
  812. #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
  813. MFREE(sii->osh, sii, sizeof(si_info_t));
  814. }
  815. void *
  816. si_osh(si_t *sih)
  817. {
  818. si_info_t *sii;
  819. sii = SI_INFO(sih);
  820. return sii->osh;
  821. }
  822. void
  823. si_setosh(si_t *sih, osl_t *osh)
  824. {
  825. si_info_t *sii;
  826. sii = SI_INFO(sih);
  827. if (sii->osh != NULL) {
  828. SI_ERROR(("osh is already set....\n"));
  829. ASSERT(!sii->osh);
  830. }
  831. sii->osh = osh;
  832. }
  833. /** register driver interrupt disabling and restoring callback functions */
  834. void
  835. si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
  836. void *intrsenabled_fn, void *intr_arg)
  837. {
  838. si_info_t *sii = SI_INFO(sih);
  839. si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
  840. sii->intr_arg = intr_arg;
  841. sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn;
  842. sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn;
  843. sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn;
  844. /* save current core id. when this function called, the current core
  845. * must be the core which provides driver functions(il, et, wl, etc.)
  846. */
  847. sii->dev_coreid = cores_info->coreid[sii->curidx];
  848. }
  849. void
  850. si_deregister_intr_callback(si_t *sih)
  851. {
  852. si_info_t *sii;
  853. sii = SI_INFO(sih);
  854. sii->intrsoff_fn = NULL;
  855. sii->intrsrestore_fn = NULL;
  856. sii->intrsenabled_fn = NULL;
  857. }
  858. uint
  859. si_intflag(si_t *sih)
  860. {
  861. si_info_t *sii = SI_INFO(sih);
  862. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  863. return sb_intflag(sih);
  864. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  865. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  866. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  867. return R_REG(sii->osh, ((uint32 *)(uintptr)
  868. (sii->oob_router + OOB_STATUSA)));
  869. else {
  870. ASSERT(0);
  871. return 0;
  872. }
  873. }
  874. uint
  875. si_flag(si_t *sih)
  876. {
  877. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  878. return sb_flag(sih);
  879. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  880. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  881. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  882. return ai_flag(sih);
  883. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  884. return ub_flag(sih);
  885. else {
  886. ASSERT(0);
  887. return 0;
  888. }
  889. }
  890. uint
  891. si_flag_alt(si_t *sih)
  892. {
  893. if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  894. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  895. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  896. return ai_flag_alt(sih);
  897. else {
  898. ASSERT(0);
  899. return 0;
  900. }
  901. }
  902. void
  903. si_setint(si_t *sih, int siflag)
  904. {
  905. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  906. sb_setint(sih, siflag);
  907. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  908. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  909. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  910. ai_setint(sih, siflag);
  911. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  912. ub_setint(sih, siflag);
  913. else
  914. ASSERT(0);
  915. }
  916. uint32
  917. si_oobr_baseaddr(si_t *sih, bool second)
  918. {
  919. si_info_t *sii = SI_INFO(sih);
  920. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  921. return 0;
  922. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  923. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  924. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  925. return (second ? sii->oob_router1 : sii->oob_router);
  926. else {
  927. ASSERT(0);
  928. return 0;
  929. }
  930. }
  931. uint
  932. si_coreid(si_t *sih)
  933. {
  934. si_info_t *sii = SI_INFO(sih);
  935. si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
  936. return cores_info->coreid[sii->curidx];
  937. }
  938. uint
  939. si_coreidx(si_t *sih)
  940. {
  941. si_info_t *sii;
  942. sii = SI_INFO(sih);
  943. return sii->curidx;
  944. }
  945. volatile void *
  946. si_d11_switch_addrbase(si_t *sih, uint coreunit)
  947. {
  948. return si_setcore(sih, D11_CORE_ID, coreunit);
  949. }
  950. /** return the core-type instantiation # of the current core */
  951. uint
  952. si_coreunit(si_t *sih)
  953. {
  954. si_info_t *sii = SI_INFO(sih);
  955. si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
  956. uint idx;
  957. uint coreid;
  958. uint coreunit;
  959. uint i;
  960. coreunit = 0;
  961. idx = sii->curidx;
  962. ASSERT(GOODREGS(sii->curmap));
  963. coreid = si_coreid(sih);
  964. /* count the cores of our type */
  965. for (i = 0; i < idx; i++)
  966. if (cores_info->coreid[i] == coreid)
  967. coreunit++;
  968. return (coreunit);
  969. }
  970. uint
  971. si_corevendor(si_t *sih)
  972. {
  973. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  974. return sb_corevendor(sih);
  975. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  976. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  977. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  978. return ai_corevendor(sih);
  979. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  980. return ub_corevendor(sih);
  981. else {
  982. ASSERT(0);
  983. return 0;
  984. }
  985. }
  986. bool
  987. si_backplane64(si_t *sih)
  988. {
  989. return ((sih->cccaps & CC_CAP_BKPLN64) != 0);
  990. }
  991. uint
  992. si_corerev(si_t *sih)
  993. {
  994. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  995. return sb_corerev(sih);
  996. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  997. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  998. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  999. return ai_corerev(sih);
  1000. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1001. return ub_corerev(sih);
  1002. else {
  1003. ASSERT(0);
  1004. return 0;
  1005. }
  1006. }
  1007. uint
  1008. si_corerev_minor(si_t *sih)
  1009. {
  1010. if (CHIPTYPE(sih->socitype) == SOCI_AI) {
  1011. return ai_corerev_minor(sih);
  1012. } else {
  1013. return 0;
  1014. }
  1015. }
  1016. /* return index of coreid or BADIDX if not found */
  1017. uint
  1018. si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
  1019. {
  1020. si_info_t *sii = SI_INFO(sih);
  1021. si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
  1022. uint found;
  1023. uint i;
  1024. found = 0;
  1025. for (i = 0; i < sii->numcores; i++)
  1026. if (cores_info->coreid[i] == coreid) {
  1027. if (found == coreunit)
  1028. return (i);
  1029. found++;
  1030. }
  1031. return (BADIDX);
  1032. }
  1033. /** return total coreunit of coreid or zero if not found */
  1034. uint
  1035. si_numcoreunits(si_t *sih, uint coreid)
  1036. {
  1037. si_info_t *sii = SI_INFO(sih);
  1038. si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
  1039. uint found = 0;
  1040. uint i;
  1041. for (i = 0; i < sii->numcores; i++) {
  1042. if (cores_info->coreid[i] == coreid) {
  1043. found++;
  1044. }
  1045. }
  1046. return found;
  1047. }
  1048. /** return total D11 coreunits */
  1049. uint
  1050. BCMRAMFN(si_numd11coreunits)(si_t *sih)
  1051. {
  1052. uint found = 0;
  1053. found = si_numcoreunits(sih, D11_CORE_ID);
  1054. #if defined(WLRSDB) && defined(WLRSDB_DISABLED)
  1055. /* If RSDB functionality is compiled out,
  1056. * then ignore any D11 cores beyond the first
  1057. * Used in norsdb dongle build variants for rsdb chip.
  1058. */
  1059. found = 1;
  1060. #endif /* defined(WLRSDB) && !defined(WLRSDB_DISABLED) */
  1061. return found;
  1062. }
  1063. /** return list of found cores */
  1064. uint
  1065. si_corelist(si_t *sih, uint coreid[])
  1066. {
  1067. si_info_t *sii = SI_INFO(sih);
  1068. si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
  1069. bcopy((uchar*)cores_info->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint)));
  1070. return (sii->numcores);
  1071. }
  1072. /** return current wrapper mapping */
  1073. void *
  1074. si_wrapperregs(si_t *sih)
  1075. {
  1076. si_info_t *sii;
  1077. sii = SI_INFO(sih);
  1078. ASSERT(GOODREGS(sii->curwrap));
  1079. return (sii->curwrap);
  1080. }
  1081. /** return current register mapping */
  1082. volatile void *
  1083. si_coreregs(si_t *sih)
  1084. {
  1085. si_info_t *sii;
  1086. sii = SI_INFO(sih);
  1087. ASSERT(GOODREGS(sii->curmap));
  1088. return (sii->curmap);
  1089. }
  1090. /**
  1091. * This function changes logical "focus" to the indicated core;
  1092. * must be called with interrupts off.
  1093. * Moreover, callers should keep interrupts off during switching out of and back to d11 core
  1094. */
  1095. volatile void *
  1096. si_setcore(si_t *sih, uint coreid, uint coreunit)
  1097. {
  1098. uint idx;
  1099. idx = si_findcoreidx(sih, coreid, coreunit);
  1100. if (!GOODIDX(idx))
  1101. return (NULL);
  1102. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1103. return sb_setcoreidx(sih, idx);
  1104. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1105. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1106. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1107. return ai_setcoreidx(sih, idx);
  1108. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1109. return ub_setcoreidx(sih, idx);
  1110. else {
  1111. ASSERT(0);
  1112. return NULL;
  1113. }
  1114. }
  1115. volatile void *
  1116. si_setcoreidx(si_t *sih, uint coreidx)
  1117. {
  1118. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1119. return sb_setcoreidx(sih, coreidx);
  1120. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1121. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1122. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1123. return ai_setcoreidx(sih, coreidx);
  1124. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1125. return ub_setcoreidx(sih, coreidx);
  1126. else {
  1127. ASSERT(0);
  1128. return NULL;
  1129. }
  1130. }
  1131. /** Turn off interrupt as required by sb_setcore, before switch core */
  1132. volatile void *
  1133. si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
  1134. {
  1135. volatile void *cc;
  1136. si_info_t *sii = SI_INFO(sih);
  1137. if (SI_FAST(sii)) {
  1138. /* Overloading the origidx variable to remember the coreid,
  1139. * this works because the core ids cannot be confused with
  1140. * core indices.
  1141. */
  1142. *origidx = coreid;
  1143. if (coreid == CC_CORE_ID)
  1144. return (volatile void *)CCREGS_FAST(sii);
  1145. else if (coreid == BUSCORETYPE(sih->buscoretype))
  1146. return (volatile void *)PCIEREGS(sii);
  1147. }
  1148. INTR_OFF(sii, *intr_val);
  1149. *origidx = sii->curidx;
  1150. cc = si_setcore(sih, coreid, 0);
  1151. ASSERT(cc != NULL);
  1152. return cc;
  1153. }
  1154. /* restore coreidx and restore interrupt */
  1155. void
  1156. si_restore_core(si_t *sih, uint coreid, uint intr_val)
  1157. {
  1158. si_info_t *sii = SI_INFO(sih);
  1159. if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == BUSCORETYPE(sih->buscoretype))))
  1160. return;
  1161. si_setcoreidx(sih, coreid);
  1162. INTR_RESTORE(sii, intr_val);
  1163. }
  1164. int
  1165. si_numaddrspaces(si_t *sih)
  1166. {
  1167. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1168. return sb_numaddrspaces(sih);
  1169. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1170. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1171. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1172. return ai_numaddrspaces(sih);
  1173. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1174. return ub_numaddrspaces(sih);
  1175. else {
  1176. ASSERT(0);
  1177. return 0;
  1178. }
  1179. }
  1180. /* Return the address of the nth address space in the current core
  1181. * Arguments:
  1182. * sih : Pointer to struct si_t
  1183. * spidx : slave port index
  1184. * baidx : base address index
  1185. */
  1186. uint32
  1187. si_addrspace(si_t *sih, uint spidx, uint baidx)
  1188. {
  1189. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1190. return sb_addrspace(sih, baidx);
  1191. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1192. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1193. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1194. return ai_addrspace(sih, spidx, baidx);
  1195. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1196. return ub_addrspace(sih, baidx);
  1197. else {
  1198. ASSERT(0);
  1199. return 0;
  1200. }
  1201. }
  1202. /* Return the size of the nth address space in the current core
  1203. * Arguments:
  1204. * sih : Pointer to struct si_t
  1205. * spidx : slave port index
  1206. * baidx : base address index
  1207. */
  1208. uint32
  1209. si_addrspacesize(si_t *sih, uint spidx, uint baidx)
  1210. {
  1211. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1212. return sb_addrspacesize(sih, baidx);
  1213. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1214. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1215. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1216. return ai_addrspacesize(sih, spidx, baidx);
  1217. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1218. return ub_addrspacesize(sih, baidx);
  1219. else {
  1220. ASSERT(0);
  1221. return 0;
  1222. }
  1223. }
  1224. void
  1225. si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size)
  1226. {
  1227. /* Only supported for SOCI_AI */
  1228. if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1229. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1230. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1231. ai_coreaddrspaceX(sih, asidx, addr, size);
  1232. else
  1233. *size = 0;
  1234. }
  1235. uint32
  1236. si_core_cflags(si_t *sih, uint32 mask, uint32 val)
  1237. {
  1238. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1239. return sb_core_cflags(sih, mask, val);
  1240. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1241. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1242. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1243. return ai_core_cflags(sih, mask, val);
  1244. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1245. return ub_core_cflags(sih, mask, val);
  1246. else {
  1247. ASSERT(0);
  1248. return 0;
  1249. }
  1250. }
  1251. void
  1252. si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
  1253. {
  1254. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1255. sb_core_cflags_wo(sih, mask, val);
  1256. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1257. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1258. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1259. ai_core_cflags_wo(sih, mask, val);
  1260. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1261. ub_core_cflags_wo(sih, mask, val);
  1262. else
  1263. ASSERT(0);
  1264. }
  1265. uint32
  1266. si_core_sflags(si_t *sih, uint32 mask, uint32 val)
  1267. {
  1268. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1269. return sb_core_sflags(sih, mask, val);
  1270. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1271. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1272. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1273. return ai_core_sflags(sih, mask, val);
  1274. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1275. return ub_core_sflags(sih, mask, val);
  1276. else {
  1277. ASSERT(0);
  1278. return 0;
  1279. }
  1280. }
  1281. void
  1282. si_commit(si_t *sih)
  1283. {
  1284. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1285. sb_commit(sih);
  1286. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1287. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1288. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1289. ;
  1290. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1291. ;
  1292. else {
  1293. ASSERT(0);
  1294. }
  1295. }
  1296. bool
  1297. si_iscoreup(si_t *sih)
  1298. {
  1299. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1300. return sb_iscoreup(sih);
  1301. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1302. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1303. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1304. return ai_iscoreup(sih);
  1305. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1306. return ub_iscoreup(sih);
  1307. else {
  1308. ASSERT(0);
  1309. return FALSE;
  1310. }
  1311. }
  1312. uint
  1313. si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
  1314. {
  1315. /* only for AI back plane chips */
  1316. if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1317. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1318. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1319. return (ai_wrap_reg(sih, offset, mask, val));
  1320. return 0;
  1321. }
  1322. /* si_backplane_access is used to read full backplane address from host for PCIE FD
  1323. * it uses secondary bar-0 window which lies at an offset of 16K from primary bar-0
  1324. * Provides support for read/write of 1/2/4 bytes of backplane address
  1325. * Can be used to read/write
  1326. * 1. core regs
  1327. * 2. Wrapper regs
  1328. * 3. memory
  1329. * 4. BT area
  1330. * For accessing any 32 bit backplane address, [31 : 12] of backplane should be given in "region"
  1331. * [11 : 0] should be the "regoff"
  1332. * for reading 4 bytes from reg 0x200 of d11 core use it like below
  1333. * : si_backplane_access(sih, 0x18001000, 0x200, 4, 0, TRUE)
  1334. */
  1335. static int si_backplane_addr_sane(uint addr, uint size)
  1336. {
  1337. int bcmerror = BCME_OK;
  1338. /* For 2 byte access, address has to be 2 byte aligned */
  1339. if (size == 2) {
  1340. if (addr & 0x1) {
  1341. bcmerror = BCME_ERROR;
  1342. }
  1343. }
  1344. /* For 4 byte access, address has to be 4 byte aligned */
  1345. if (size == 4) {
  1346. if (addr & 0x3) {
  1347. bcmerror = BCME_ERROR;
  1348. }
  1349. }
  1350. return bcmerror;
  1351. }
  1352. void
  1353. si_invalidate_second_bar0win(si_t *sih)
  1354. {
  1355. si_info_t *sii = SI_INFO(sih);
  1356. sii->second_bar0win = ~0x0;
  1357. }
  1358. int
  1359. si_backplane_access(si_t *sih, uint addr, uint size, uint *val, bool read)
  1360. {
  1361. volatile uint32 *r = NULL;
  1362. uint32 region = 0;
  1363. si_info_t *sii = SI_INFO(sih);
  1364. /* Valid only for pcie bus */
  1365. if (BUSTYPE(sih->bustype) != PCI_BUS) {
  1366. SI_ERROR(("Valid only for pcie bus \n"));
  1367. return BCME_ERROR;
  1368. }
  1369. /* Split adrr into region and address offset */
  1370. region = (addr & (0xFFFFF << 12));
  1371. addr = addr & 0xFFF;
  1372. /* check for address and size sanity */
  1373. if (si_backplane_addr_sane(addr, size) != BCME_OK)
  1374. return BCME_ERROR;
  1375. /* Update window if required */
  1376. if (sii->second_bar0win != region) {
  1377. OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_CORE2_WIN, 4, region);
  1378. sii->second_bar0win = region;
  1379. }
  1380. /* Estimate effective address
  1381. * sii->curmap : bar-0 virtual address
  1382. * PCI_SECOND_BAR0_OFFSET : secondar bar-0 offset
  1383. * regoff : actual reg offset
  1384. */
  1385. r = (volatile uint32 *)((volatile char *)sii->curmap + PCI_SECOND_BAR0_OFFSET + addr);
  1386. SI_VMSG(("si curmap %p region %x regaddr %x effective addr %p READ %d\n",
  1387. (volatile char*)sii->curmap, region, addr, r, read));
  1388. switch (size) {
  1389. case sizeof(uint8) :
  1390. if (read)
  1391. *val = R_REG(sii->osh, (volatile uint8*)r);
  1392. else
  1393. W_REG(sii->osh, (volatile uint8*)r, *val);
  1394. break;
  1395. case sizeof(uint16) :
  1396. if (read)
  1397. *val = R_REG(sii->osh, (volatile uint16*)r);
  1398. else
  1399. W_REG(sii->osh, (volatile uint16*)r, *val);
  1400. break;
  1401. case sizeof(uint32) :
  1402. if (read)
  1403. *val = R_REG(sii->osh, (volatile uint32*)r);
  1404. else
  1405. W_REG(sii->osh, (volatile uint32*)r, *val);
  1406. break;
  1407. default :
  1408. SI_ERROR(("Invalid size %d \n", size));
  1409. return (BCME_ERROR);
  1410. break;
  1411. }
  1412. return (BCME_OK);
  1413. }
  1414. uint
  1415. si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
  1416. {
  1417. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1418. return sb_corereg(sih, coreidx, regoff, mask, val);
  1419. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1420. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1421. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1422. return ai_corereg(sih, coreidx, regoff, mask, val);
  1423. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1424. return ub_corereg(sih, coreidx, regoff, mask, val);
  1425. else {
  1426. ASSERT(0);
  1427. return 0;
  1428. }
  1429. }
  1430. uint
  1431. si_corereg_writeonly(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
  1432. {
  1433. return ai_corereg_writeonly(sih, coreidx, regoff, mask, val);
  1434. }
  1435. /** ILP sensitive register access needs special treatment to avoid backplane stalls */
  1436. bool si_pmu_is_ilp_sensitive(uint32 idx, uint regoff)
  1437. {
  1438. if (idx == SI_CC_IDX) {
  1439. if (CHIPCREGS_ILP_SENSITIVE(regoff))
  1440. return TRUE;
  1441. } else if (PMUREGS_ILP_SENSITIVE(regoff)) {
  1442. return TRUE;
  1443. }
  1444. return FALSE;
  1445. }
  1446. /** 'idx' should refer either to the chipcommon core or the PMU core */
  1447. uint
  1448. si_pmu_corereg(si_t *sih, uint32 idx, uint regoff, uint mask, uint val)
  1449. {
  1450. int pmustatus_offset;
  1451. /* prevent backplane stall on double write to 'ILP domain' registers in the PMU */
  1452. if (mask != 0 && PMUREV(sih->pmurev) >= 22 &&
  1453. si_pmu_is_ilp_sensitive(idx, regoff)) {
  1454. pmustatus_offset = AOB_ENAB(sih) ? OFFSETOF(pmuregs_t, pmustatus) :
  1455. OFFSETOF(chipcregs_t, pmustatus);
  1456. while (si_corereg(sih, idx, pmustatus_offset, 0, 0) & PST_SLOW_WR_PENDING)
  1457. {};
  1458. }
  1459. return si_corereg(sih, idx, regoff, mask, val);
  1460. }
  1461. /*
  1462. * If there is no need for fiddling with interrupts or core switches (typically silicon
  1463. * back plane registers, pci registers and chipcommon registers), this function
  1464. * returns the register offset on this core to a mapped address. This address can
  1465. * be used for W_REG/R_REG directly.
  1466. *
  1467. * For accessing registers that would need a core switch, this function will return
  1468. * NULL.
  1469. */
  1470. volatile uint32 *
  1471. si_corereg_addr(si_t *sih, uint coreidx, uint regoff)
  1472. {
  1473. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1474. return sb_corereg_addr(sih, coreidx, regoff);
  1475. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1476. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1477. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1478. return ai_corereg_addr(sih, coreidx, regoff);
  1479. else {
  1480. return 0;
  1481. }
  1482. }
  1483. void
  1484. si_core_disable(si_t *sih, uint32 bits)
  1485. {
  1486. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1487. sb_core_disable(sih, bits);
  1488. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1489. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1490. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1491. ai_core_disable(sih, bits);
  1492. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1493. ub_core_disable(sih, bits);
  1494. }
  1495. void
  1496. si_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
  1497. {
  1498. if (CHIPTYPE(sih->socitype) == SOCI_SB)
  1499. sb_core_reset(sih, bits, resetbits);
  1500. else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1501. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1502. (CHIPTYPE(sih->socitype) == SOCI_NAI))
  1503. ai_core_reset(sih, bits, resetbits);
  1504. else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
  1505. ub_core_reset(sih, bits, resetbits);
  1506. }
  1507. /** Run bist on current core. Caller needs to take care of core-specific bist hazards */
  1508. int
  1509. si_corebist(si_t *sih)
  1510. {
  1511. uint32 cflags;
  1512. int result = 0;
  1513. /* Read core control flags */
  1514. cflags = si_core_cflags(sih, 0, 0);
  1515. /* Set bist & fgc */
  1516. si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC));
  1517. /* Wait for bist done */
  1518. SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000);
  1519. if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR)
  1520. result = BCME_ERROR;
  1521. /* Reset core control flags */
  1522. si_core_cflags(sih, 0xffff, cflags);
  1523. return result;
  1524. }
  1525. uint
  1526. si_num_slaveports(si_t *sih, uint coreid)
  1527. {
  1528. uint idx = si_findcoreidx(sih, coreid, 0);
  1529. uint num = 0;
  1530. if (idx != BADIDX) {
  1531. if (CHIPTYPE(sih->socitype) == SOCI_AI) {
  1532. num = ai_num_slaveports(sih, idx);
  1533. }
  1534. }
  1535. return num;
  1536. }
  1537. uint32
  1538. si_get_slaveport_addr(si_t *sih, uint spidx, uint baidx, uint core_id, uint coreunit)
  1539. {
  1540. si_info_t *sii = SI_INFO(sih);
  1541. uint origidx = sii->curidx;
  1542. uint32 addr = 0x0;
  1543. if (!((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1544. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1545. (CHIPTYPE(sih->socitype) == SOCI_NAI)))
  1546. goto done;
  1547. si_setcore(sih, core_id, coreunit);
  1548. addr = ai_addrspace(sih, spidx, baidx);
  1549. si_setcoreidx(sih, origidx);
  1550. done:
  1551. return addr;
  1552. }
  1553. uint32
  1554. si_get_d11_slaveport_addr(si_t *sih, uint spidx, uint baidx, uint coreunit)
  1555. {
  1556. si_info_t *sii = SI_INFO(sih);
  1557. uint origidx = sii->curidx;
  1558. uint32 addr = 0x0;
  1559. if (!((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  1560. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
  1561. (CHIPTYPE(sih->socitype) == SOCI_NAI)))
  1562. goto done;
  1563. si_setcore(sih, D11_CORE_ID, coreunit);
  1564. addr = ai_addrspace(sih, spidx, baidx);
  1565. si_setcoreidx(sih, origidx);
  1566. done:
  1567. return addr;
  1568. }
  1569. static uint32
  1570. factor6(uint32 x)
  1571. {
  1572. switch (x) {
  1573. case CC_F6_2: return 2;
  1574. case CC_F6_3: return 3;
  1575. case CC_F6_4: return 4;
  1576. case CC_F6_5: return 5;
  1577. case CC_F6_6: return 6;
  1578. case CC_F6_7: return 7;
  1579. default: return 0;
  1580. }
  1581. }
  1582. /*
  1583. * Divide the clock by the divisor with protection for
  1584. * a zero divisor.
  1585. */
  1586. static uint32
  1587. divide_clock(uint32 clock, uint32 div)
  1588. {
  1589. return div ? clock / div : 0;
  1590. }
  1591. /** calculate the speed the SI would run at given a set of clockcontrol values */
  1592. uint32
  1593. si_clock_rate(uint32 pll_type, uint32 n, uint32 m)
  1594. {
  1595. uint32 n1, n2, clock, m1, m2, m3, mc;
  1596. n1 = n & CN_N1_MASK;
  1597. n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
  1598. if (pll_type == PLL_TYPE6) {
  1599. if (m & CC_T6_MMASK)
  1600. return CC_T6_M1;
  1601. else
  1602. return CC_T6_M0;
  1603. } else if ((pll_type == PLL_TYPE1) ||
  1604. (pll_type == PLL_TYPE3) ||
  1605. (pll_type == PLL_TYPE4) ||
  1606. (pll_type == PLL_TYPE7)) {
  1607. n1 = factor6(n1);
  1608. n2 += CC_F5_BIAS;
  1609. } else if (pll_type == PLL_TYPE2) {
  1610. n1 += CC_T2_BIAS;
  1611. n2 += CC_T2_BIAS;
  1612. ASSERT((n1 >= 2) && (n1 <= 7));
  1613. ASSERT((n2 >= 5) && (n2 <= 23));
  1614. } else if (pll_type == PLL_TYPE5) {
  1615. return (100000000);
  1616. } else
  1617. ASSERT(0);
  1618. /* PLL types 3 and 7 use BASE2 (25Mhz) */
  1619. if ((pll_type == PLL_TYPE3) ||
  1620. (pll_type == PLL_TYPE7)) {
  1621. clock = CC_CLOCK_BASE2 * n1 * n2;
  1622. } else
  1623. clock = CC_CLOCK_BASE1 * n1 * n2;
  1624. if (clock == 0)
  1625. return 0;
  1626. m1 = m & CC_M1_MASK;
  1627. m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
  1628. m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
  1629. mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
  1630. if ((pll_type == PLL_TYPE1) ||
  1631. (pll_type == PLL_TYPE3) ||
  1632. (pll_type == PLL_TYPE4) ||
  1633. (pll_type == PLL_TYPE7)) {
  1634. m1 = factor6(m1);
  1635. if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
  1636. m2 += CC_F5_BIAS;
  1637. else
  1638. m2 = factor6(m2);
  1639. m3 = factor6(m3);
  1640. switch (mc) {
  1641. case CC_MC_BYPASS: return (clock);
  1642. case CC_MC_M1: return divide_clock(clock, m1);
  1643. case CC_MC_M1M2: return divide_clock(clock, m1 * m2);
  1644. case CC_MC_M1M2M3: return divide_clock(clock, m1 * m2 * m3);
  1645. case CC_MC_M1M3: return divide_clock(clock, m1 * m3);
  1646. default: return (0);
  1647. }
  1648. } else {
  1649. ASSERT(pll_type == PLL_TYPE2);
  1650. m1 += CC_T2_BIAS;
  1651. m2 += CC_T2M2_BIAS;
  1652. m3 += CC_T2_BIAS;
  1653. ASSERT((m1 >= 2) && (m1 <= 7));
  1654. ASSERT((m2 >= 3) && (m2 <= 10));
  1655. ASSERT((m3 >= 2) && (m3 <= 7));
  1656. if ((mc & CC_T2MC_M1BYP) == 0)
  1657. clock /= m1;
  1658. if ((mc & CC_T2MC_M2BYP) == 0)
  1659. clock /= m2;
  1660. if ((mc & CC_T2MC_M3BYP) == 0)
  1661. clock /= m3;
  1662. return (clock);
  1663. }
  1664. }
  1665. /**
  1666. * Some chips could have multiple host interfaces, however only one will be active.
  1667. * For a given chip. Depending pkgopt and cc_chipst return the active host interface.
  1668. */
  1669. uint
  1670. si_chip_hostif(si_t *sih)
  1671. {
  1672. uint hosti = 0;
  1673. switch (CHIPID(sih->chip)) {
  1674. case BCM43018_CHIP_ID:
  1675. case BCM43430_CHIP_ID:
  1676. hosti = CHIP_HOSTIF_SDIOMODE;
  1677. break;
  1678. case BCM43012_CHIP_ID:
  1679. hosti = CHIP_HOSTIF_SDIOMODE;
  1680. break;
  1681. CASE_BCM43602_CHIP:
  1682. hosti = CHIP_HOSTIF_PCIEMODE;
  1683. break;
  1684. case BCM4360_CHIP_ID:
  1685. /* chippkg bit-0 == 0 is PCIE only pkgs
  1686. * chippkg bit-0 == 1 has both PCIE and USB cores enabled
  1687. */
  1688. if ((sih->chippkg & 0x1) && (sih->chipst & CST4360_MODE_USB))
  1689. hosti = CHIP_HOSTIF_USBMODE;
  1690. else
  1691. hosti = CHIP_HOSTIF_PCIEMODE;
  1692. break;
  1693. case BCM4335_CHIP_ID:
  1694. /* TBD: like in 4360, do we need to check pkg? */
  1695. if (CST4335_CHIPMODE_USB20D(sih->chipst))
  1696. hosti = CHIP_HOSTIF_USBMODE;
  1697. else if (CST4335_CHIPMODE_SDIOD(sih->chipst))
  1698. hosti = CHIP_HOSTIF_SDIOMODE;
  1699. else
  1700. hosti = CHIP_HOSTIF_PCIEMODE;
  1701. break;
  1702. CASE_BCM4345_CHIP:
  1703. if (CST4345_CHIPMODE_USB20D(sih->chipst) || CST4345_CHIPMODE_HSIC(sih->chipst))
  1704. hosti = CHIP_HOSTIF_USBMODE;
  1705. else if (CST4345_CHIPMODE_SDIOD(sih->chipst))
  1706. hosti = CHIP_HOSTIF_SDIOMODE;
  1707. else if (CST4345_CHIPMODE_PCIE(sih->chipst))
  1708. hosti = CHIP_HOSTIF_PCIEMODE;
  1709. break;
  1710. case BCM4349_CHIP_GRPID:
  1711. case BCM53573_CHIP_GRPID:
  1712. if (CST4349_CHIPMODE_SDIOD(sih->chipst))
  1713. hosti = CHIP_HOSTIF_SDIOMODE;
  1714. else if (CST4349_CHIPMODE_PCIE(sih->chipst))
  1715. hosti = CHIP_HOSTIF_PCIEMODE;
  1716. break;
  1717. case BCM4364_CHIP_ID:
  1718. if (CST4364_CHIPMODE_SDIOD(sih->chipst))
  1719. hosti = CHIP_HOSTIF_SDIOMODE;
  1720. else if (CST4364_CHIPMODE_PCIE(sih->chipst))
  1721. hosti = CHIP_HOSTIF_PCIEMODE;
  1722. break;
  1723. case BCM4373_CHIP_ID:
  1724. if (CST4373_CHIPMODE_USB20D(sih->chipst))
  1725. hosti = CHIP_HOSTIF_USBMODE;
  1726. else if (CST4373_CHIPMODE_SDIOD(sih->chipst))
  1727. hosti = CHIP_HOSTIF_SDIOMODE;
  1728. else if (CST4373_CHIPMODE_PCIE(sih->chipst))
  1729. hosti = CHIP_HOSTIF_PCIEMODE;
  1730. break;
  1731. case BCM4347_CHIP_GRPID:
  1732. if (CST4347_CHIPMODE_SDIOD(sih->chipst))
  1733. hosti = CHIP_HOSTIF_SDIOMODE;
  1734. else if (CST4347_CHIPMODE_PCIE(sih->chipst))
  1735. hosti = CHIP_HOSTIF_PCIEMODE;
  1736. break;
  1737. case BCM4369_CHIP_GRPID:
  1738. if (CST4369_CHIPMODE_SDIOD(sih->chipst))
  1739. hosti = CHIP_HOSTIF_SDIOMODE;
  1740. else if (CST4369_CHIPMODE_PCIE(sih->chipst))
  1741. hosti = CHIP_HOSTIF_PCIEMODE;
  1742. break;
  1743. #ifdef CHIPS_CUSTOMER_HW6
  1744. case BCM4368_CHIP_GRPID:
  1745. hosti = CHIP_HOSTIF_PCIEMODE;
  1746. break;
  1747. #endif /* CHIPS_CUSTOMER_HW6 */
  1748. case BCM4350_CHIP_ID:
  1749. case BCM4354_CHIP_ID:
  1750. case BCM43556_CHIP_ID:
  1751. case BCM43558_CHIP_ID:
  1752. case BCM43566_CHIP_ID:
  1753. case BCM43568_CHIP_ID:
  1754. case BCM43569_CHIP_ID:
  1755. case BCM43570_CHIP_ID:
  1756. case BCM4358_CHIP_ID:
  1757. if (CST4350_CHIPMODE_USB20D(sih->chipst) ||
  1758. CST4350_CHIPMODE_HSIC20D(sih->chipst) ||
  1759. CST4350_CHIPMODE_USB30D(sih->chipst) ||
  1760. CST4350_CHIPMODE_USB30D_WL(sih->chipst) ||
  1761. CST4350_CHIPMODE_HSIC30D(sih->chipst))
  1762. hosti = CHIP_HOSTIF_USBMODE;
  1763. else if (CST4350_CHIPMODE_SDIOD(sih->chipst))
  1764. hosti = CHIP_HOSTIF_SDIOMODE;
  1765. else if (CST4350_CHIPMODE_PCIE(sih->chipst))
  1766. hosti = CHIP_HOSTIF_PCIEMODE;
  1767. break;
  1768. default:
  1769. break;
  1770. }
  1771. return hosti;
  1772. }
  1773. /** set chip watchdog reset timer to fire in 'ticks' */
  1774. void
  1775. si_watchdog(si_t *sih, uint ticks)
  1776. {
  1777. uint nb, maxt;
  1778. uint pmu_wdt = 1;
  1779. if (PMUCTL_ENAB(sih) && pmu_wdt) {
  1780. nb = (CCREV(sih->ccrev) < 26) ? 16 : ((CCREV(sih->ccrev) >= 37) ? 32 : 24);
  1781. /* The mips compiler uses the sllv instruction,
  1782. * so we specially handle the 32-bit case.
  1783. */
  1784. if (nb == 32)
  1785. maxt = 0xffffffff;
  1786. else
  1787. maxt = ((1 << nb) - 1);
  1788. if (ticks == 1)
  1789. ticks = 2;
  1790. else if (ticks > maxt)
  1791. ticks = maxt;
  1792. if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
  1793. PMU_REG_NEW(sih, min_res_mask, ~0, DEFAULT_43012_MIN_RES_MASK);
  1794. PMU_REG_NEW(sih, watchdog_res_mask, ~0, DEFAULT_43012_MIN_RES_MASK);
  1795. PMU_REG_NEW(sih, pmustatus, PST_WDRESET, PST_WDRESET);
  1796. PMU_REG_NEW(sih, pmucontrol_ext, PCTL_EXT_FASTLPO_SWENAB, 0);
  1797. SPINWAIT((PMU_REG(sih, pmustatus, 0, 0) & PST_ILPFASTLPO),
  1798. PMU_MAX_TRANSITION_DLY);
  1799. }
  1800. pmu_corereg(sih, SI_CC_IDX, pmuwatchdog, ~0, ticks);
  1801. } else {
  1802. maxt = (1 << 28) - 1;
  1803. if (ticks > maxt)
  1804. ticks = maxt;
  1805. si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
  1806. }
  1807. }
  1808. /** trigger watchdog reset after ms milliseconds */
  1809. void
  1810. si_watchdog_ms(si_t *sih, uint32 ms)
  1811. {
  1812. si_watchdog(sih, wd_msticks * ms);
  1813. }
  1814. uint32 si_watchdog_msticks(void)
  1815. {
  1816. return wd_msticks;
  1817. }
  1818. bool
  1819. si_taclear(si_t *sih, bool details)
  1820. {
  1821. return FALSE;
  1822. }
  1823. /** return the slow clock source - LPO, XTAL, or PCI */
  1824. static uint
  1825. si_slowclk_src(si_info_t *sii)
  1826. {
  1827. chipcregs_t *cc;
  1828. ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
  1829. if (CCREV(sii->pub.ccrev) < 6) {
  1830. if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
  1831. (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) &
  1832. PCI_CFG_GPIO_SCS))
  1833. return (SCC_SS_PCI);
  1834. else
  1835. return (SCC_SS_XTAL);
  1836. } else if (CCREV(sii->pub.ccrev) < 10) {
  1837. cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx);
  1838. ASSERT(cc);
  1839. return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
  1840. } else /* Insta-clock */
  1841. return (SCC_SS_XTAL);
  1842. }
  1843. /** return the ILP (slowclock) min or max frequency */
  1844. static uint
  1845. si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
  1846. {
  1847. uint32 slowclk;
  1848. uint div;
  1849. ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
  1850. /* shouldn't be here unless we've established the chip has dynamic clk control */
  1851. ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
  1852. slowclk = si_slowclk_src(sii);
  1853. if (CCREV(sii->pub.ccrev) < 6) {
  1854. if (slowclk == SCC_SS_PCI)
  1855. return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64));
  1856. else
  1857. return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32));
  1858. } else if (CCREV(sii->pub.ccrev) < 10) {
  1859. div = 4 *
  1860. (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
  1861. if (slowclk == SCC_SS_LPO)
  1862. return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
  1863. else if (slowclk == SCC_SS_XTAL)
  1864. return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div));
  1865. else if (slowclk == SCC_SS_PCI)
  1866. return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div));
  1867. else
  1868. ASSERT(0);
  1869. } else {
  1870. /* Chipc rev 10 is InstaClock */
  1871. div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
  1872. div = 4 * (div + 1);
  1873. return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
  1874. }
  1875. return (0);
  1876. }
  1877. static void
  1878. si_clkctl_setdelay(si_info_t *sii, void *chipcregs)
  1879. {
  1880. chipcregs_t *cc = (chipcregs_t *)chipcregs;
  1881. uint slowmaxfreq, pll_delay, slowclk;
  1882. uint pll_on_delay, fref_sel_delay;
  1883. pll_delay = PLL_DELAY;
  1884. /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
  1885. * since the xtal will also be powered down by dynamic clk control logic.
  1886. */
  1887. slowclk = si_slowclk_src(sii);
  1888. if (slowclk != SCC_SS_XTAL)
  1889. pll_delay += XTAL_ON_DELAY;
  1890. /* Starting with 4318 it is ILP that is used for the delays */
  1891. slowmaxfreq = si_slowclk_freq(sii, (CCREV(sii->pub.ccrev) >= 10) ? FALSE : TRUE, cc);
  1892. pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
  1893. fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
  1894. W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
  1895. W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
  1896. }
  1897. /** initialize power control delay registers */
  1898. void
  1899. si_clkctl_init(si_t *sih)
  1900. {
  1901. si_info_t *sii;
  1902. uint origidx = 0;
  1903. chipcregs_t *cc;
  1904. bool fast;
  1905. if (!CCCTL_ENAB(sih))
  1906. return;
  1907. sii = SI_INFO(sih);
  1908. fast = SI_FAST(sii);
  1909. if (!fast) {
  1910. origidx = sii->curidx;
  1911. if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL)
  1912. return;
  1913. } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL)
  1914. return;
  1915. ASSERT(cc != NULL);
  1916. /* set all Instaclk chip ILP to 1 MHz */
  1917. if (CCREV(sih->ccrev) >= 10)
  1918. SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
  1919. (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
  1920. si_clkctl_setdelay(sii, (void *)(uintptr)cc);
  1921. OSL_DELAY(20000);
  1922. if (!fast)
  1923. si_setcoreidx(sih, origidx);
  1924. }
  1925. /** change logical "focus" to the gpio core for optimized access */
  1926. volatile void *
  1927. si_gpiosetcore(si_t *sih)
  1928. {
  1929. return (si_setcoreidx(sih, SI_CC_IDX));
  1930. }
  1931. /**
  1932. * mask & set gpiocontrol bits.
  1933. * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin.
  1934. * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated
  1935. * to some chip-specific purpose.
  1936. */
  1937. uint32
  1938. si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  1939. {
  1940. uint regoff;
  1941. regoff = 0;
  1942. /* gpios could be shared on router platforms
  1943. * ignore reservation if it's high priority (e.g., test apps)
  1944. */
  1945. if ((priority != GPIO_HI_PRIORITY) &&
  1946. (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  1947. mask = priority ? (si_gpioreservation & mask) :
  1948. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  1949. val &= mask;
  1950. }
  1951. regoff = OFFSETOF(chipcregs_t, gpiocontrol);
  1952. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  1953. }
  1954. /** mask&set gpio output enable bits */
  1955. uint32
  1956. si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  1957. {
  1958. uint regoff;
  1959. regoff = 0;
  1960. /* gpios could be shared on router platforms
  1961. * ignore reservation if it's high priority (e.g., test apps)
  1962. */
  1963. if ((priority != GPIO_HI_PRIORITY) &&
  1964. (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  1965. mask = priority ? (si_gpioreservation & mask) :
  1966. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  1967. val &= mask;
  1968. }
  1969. regoff = OFFSETOF(chipcregs_t, gpioouten);
  1970. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  1971. }
  1972. /** mask&set gpio output bits */
  1973. uint32
  1974. si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  1975. {
  1976. uint regoff;
  1977. regoff = 0;
  1978. /* gpios could be shared on router platforms
  1979. * ignore reservation if it's high priority (e.g., test apps)
  1980. */
  1981. if ((priority != GPIO_HI_PRIORITY) &&
  1982. (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  1983. mask = priority ? (si_gpioreservation & mask) :
  1984. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  1985. val &= mask;
  1986. }
  1987. regoff = OFFSETOF(chipcregs_t, gpioout);
  1988. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  1989. }
  1990. /** reserve one gpio */
  1991. uint32
  1992. si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority)
  1993. {
  1994. /* only cores on SI_BUS share GPIO's and only applcation users need to
  1995. * reserve/release GPIO
  1996. */
  1997. if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
  1998. ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
  1999. return 0xffffffff;
  2000. }
  2001. /* make sure only one bit is set */
  2002. if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
  2003. ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
  2004. return 0xffffffff;
  2005. }
  2006. /* already reserved */
  2007. if (si_gpioreservation & gpio_bitmask)
  2008. return 0xffffffff;
  2009. /* set reservation */
  2010. si_gpioreservation |= gpio_bitmask;
  2011. return si_gpioreservation;
  2012. }
  2013. /**
  2014. * release one gpio.
  2015. *
  2016. * releasing the gpio doesn't change the current value on the GPIO last write value
  2017. * persists till someone overwrites it.
  2018. */
  2019. uint32
  2020. si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority)
  2021. {
  2022. /* only cores on SI_BUS share GPIO's and only applcation users need to
  2023. * reserve/release GPIO
  2024. */
  2025. if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
  2026. ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
  2027. return 0xffffffff;
  2028. }
  2029. /* make sure only one bit is set */
  2030. if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
  2031. ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
  2032. return 0xffffffff;
  2033. }
  2034. /* already released */
  2035. if (!(si_gpioreservation & gpio_bitmask))
  2036. return 0xffffffff;
  2037. /* clear reservation */
  2038. si_gpioreservation &= ~gpio_bitmask;
  2039. return si_gpioreservation;
  2040. }
  2041. /* return the current gpioin register value */
  2042. uint32
  2043. si_gpioin(si_t *sih)
  2044. {
  2045. uint regoff;
  2046. regoff = OFFSETOF(chipcregs_t, gpioin);
  2047. return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0));
  2048. }
  2049. /* mask&set gpio interrupt polarity bits */
  2050. uint32
  2051. si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  2052. {
  2053. uint regoff;
  2054. /* gpios could be shared on router platforms */
  2055. if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  2056. mask = priority ? (si_gpioreservation & mask) :
  2057. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  2058. val &= mask;
  2059. }
  2060. regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
  2061. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  2062. }
  2063. /* mask&set gpio interrupt mask bits */
  2064. uint32
  2065. si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  2066. {
  2067. uint regoff;
  2068. /* gpios could be shared on router platforms */
  2069. if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  2070. mask = priority ? (si_gpioreservation & mask) :
  2071. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  2072. val &= mask;
  2073. }
  2074. regoff = OFFSETOF(chipcregs_t, gpiointmask);
  2075. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  2076. }
  2077. uint32
  2078. si_gpioeventintmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
  2079. {
  2080. uint regoff;
  2081. /* gpios could be shared on router platforms */
  2082. if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
  2083. mask = priority ? (si_gpioreservation & mask) :
  2084. ((si_gpioreservation | mask) & ~(si_gpioreservation));
  2085. val &= mask;
  2086. }
  2087. regoff = OFFSETOF(chipcregs_t, gpioeventintmask);
  2088. return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
  2089. }
  2090. /* assign the gpio to an led */
  2091. uint32
  2092. si_gpioled(si_t *sih, uint32 mask, uint32 val)
  2093. {
  2094. if (CCREV(sih->ccrev) < 16)
  2095. return 0xffffffff;
  2096. /* gpio led powersave reg */
  2097. return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val));
  2098. }
  2099. /* mask&set gpio timer val */
  2100. uint32
  2101. si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
  2102. {
  2103. if (CCREV(sih->ccrev) < 16)
  2104. return 0xffffffff;
  2105. return (si_corereg(sih, SI_CC_IDX,
  2106. OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval));
  2107. }
  2108. uint32
  2109. si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val)
  2110. {
  2111. uint offs;
  2112. if (CCREV(sih->ccrev) < 20)
  2113. return 0xffffffff;
  2114. offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup));
  2115. return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
  2116. }
  2117. uint32
  2118. si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
  2119. {
  2120. uint offs;
  2121. if (CCREV(sih->ccrev) < 11)
  2122. return 0xffffffff;
  2123. if (regtype == GPIO_REGEVT)
  2124. offs = OFFSETOF(chipcregs_t, gpioevent);
  2125. else if (regtype == GPIO_REGEVT_INTMSK)
  2126. offs = OFFSETOF(chipcregs_t, gpioeventintmask);
  2127. else if (regtype == GPIO_REGEVT_INTPOL)
  2128. offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
  2129. else
  2130. return 0xffffffff;
  2131. return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
  2132. }
  2133. uint32
  2134. si_gpio_int_enable(si_t *sih, bool enable)
  2135. {
  2136. uint offs;
  2137. if (CCREV(sih->ccrev) < 11)
  2138. return 0xffffffff;
  2139. offs = OFFSETOF(chipcregs_t, intmask);
  2140. return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
  2141. }
  2142. /** Return the size of the specified SYSMEM bank */
  2143. static uint
  2144. sysmem_banksize(si_info_t *sii, sysmemregs_t *regs, uint8 idx)
  2145. {
  2146. uint banksize, bankinfo;
  2147. uint bankidx = idx;
  2148. W_REG(sii->osh, &regs->bankidx, bankidx);
  2149. bankinfo = R_REG(sii->osh, &regs->bankinfo);
  2150. banksize = SYSMEM_BANKINFO_SZBASE * ((bankinfo & SYSMEM_BANKINFO_SZMASK) + 1);
  2151. return banksize;
  2152. }
  2153. /** Return the RAM size of the SYSMEM core */
  2154. uint32
  2155. si_sysmem_size(si_t *sih)
  2156. {
  2157. si_info_t *sii = SI_INFO(sih);
  2158. uint origidx;
  2159. uint intr_val = 0;
  2160. sysmemregs_t *regs;
  2161. bool wasup;
  2162. uint32 coreinfo;
  2163. uint memsize = 0;
  2164. uint8 i;
  2165. uint nb, nrb;
  2166. /* Block ints and save current core */
  2167. INTR_OFF(sii, intr_val);
  2168. origidx = si_coreidx(sih);
  2169. /* Switch to SYSMEM core */
  2170. if (!(regs = si_setcore(sih, SYSMEM_CORE_ID, 0)))
  2171. goto done;
  2172. /* Get info for determining size */
  2173. if (!(wasup = si_iscoreup(sih)))
  2174. si_core_reset(sih, 0, 0);
  2175. coreinfo = R_REG(sii->osh, &regs->coreinfo);
  2176. /* Number of ROM banks, SW need to skip the ROM banks. */
  2177. nrb = (coreinfo & SYSMEM_SRCI_ROMNB_MASK) >> SYSMEM_SRCI_ROMNB_SHIFT;
  2178. nb = (coreinfo & SYSMEM_SRCI_SRNB_MASK) >> SYSMEM_SRCI_SRNB_SHIFT;
  2179. for (i = 0; i < nb; i++)
  2180. memsize += sysmem_banksize(sii, regs, i + nrb);
  2181. si_setcoreidx(sih, origidx);
  2182. done:
  2183. INTR_RESTORE(sii, intr_val);
  2184. return memsize;
  2185. }
  2186. /** Return the size of the specified SOCRAM bank */
  2187. static uint
  2188. socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 idx, uint8 mem_type)
  2189. {
  2190. uint banksize, bankinfo;
  2191. uint bankidx = idx | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
  2192. ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
  2193. W_REG(sii->osh, &regs->bankidx, bankidx);
  2194. bankinfo = R_REG(sii->osh, &regs->bankinfo);
  2195. banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
  2196. return banksize;
  2197. }
  2198. void si_socram_set_bankpda(si_t *sih, uint32 bankidx, uint32 bankpda)
  2199. {
  2200. si_info_t *sii = SI_INFO(sih);
  2201. uint origidx;
  2202. uint intr_val = 0;
  2203. sbsocramregs_t *regs;
  2204. bool wasup;
  2205. uint corerev;
  2206. /* Block ints and save current core */
  2207. INTR_OFF(sii, intr_val);
  2208. origidx = si_coreidx(sih);
  2209. /* Switch to SOCRAM core */
  2210. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  2211. goto done;
  2212. if (!(wasup = si_iscoreup(sih)))
  2213. si_core_reset(sih, 0, 0);
  2214. corerev = si_corerev(sih);
  2215. if (corerev >= 16) {
  2216. W_REG(sii->osh, &regs->bankidx, bankidx);
  2217. W_REG(sii->osh, &regs->bankpda, bankpda);
  2218. }
  2219. /* Return to previous state and core */
  2220. if (!wasup)
  2221. si_core_disable(sih, 0);
  2222. si_setcoreidx(sih, origidx);
  2223. done:
  2224. INTR_RESTORE(sii, intr_val);
  2225. }
  2226. void
  2227. si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect, uint8 *remap)
  2228. {
  2229. si_info_t *sii = SI_INFO(sih);
  2230. uint origidx;
  2231. uint intr_val = 0;
  2232. sbsocramregs_t *regs;
  2233. bool wasup;
  2234. uint corerev;
  2235. /* Block ints and save current core */
  2236. INTR_OFF(sii, intr_val);
  2237. origidx = si_coreidx(sih);
  2238. if (!set)
  2239. *enable = *protect = *remap = 0;
  2240. /* Switch to SOCRAM core */
  2241. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  2242. goto done;
  2243. /* Get info for determining size */
  2244. if (!(wasup = si_iscoreup(sih)))
  2245. si_core_reset(sih, 0, 0);
  2246. corerev = si_corerev(sih);
  2247. if (corerev >= 10) {
  2248. uint32 extcinfo;
  2249. uint8 nb;
  2250. uint8 i;
  2251. uint32 bankidx, bankinfo;
  2252. extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
  2253. nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
  2254. for (i = 0; i < nb; i++) {
  2255. bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
  2256. W_REG(sii->osh, &regs->bankidx, bankidx);
  2257. bankinfo = R_REG(sii->osh, &regs->bankinfo);
  2258. if (set) {
  2259. bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK;
  2260. bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK;
  2261. bankinfo &= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK;
  2262. if (*enable) {
  2263. bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT);
  2264. if (*protect)
  2265. bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT);
  2266. if ((corerev >= 16) && *remap)
  2267. bankinfo |=
  2268. (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT);
  2269. }
  2270. W_REG(sii->osh, &regs->bankinfo, bankinfo);
  2271. } else if (i == 0) {
  2272. if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
  2273. *enable = 1;
  2274. if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK)
  2275. *protect = 1;
  2276. if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK)
  2277. *remap = 1;
  2278. }
  2279. }
  2280. }
  2281. }
  2282. /* Return to previous state and core */
  2283. if (!wasup)
  2284. si_core_disable(sih, 0);
  2285. si_setcoreidx(sih, origidx);
  2286. done:
  2287. INTR_RESTORE(sii, intr_val);
  2288. }
  2289. bool
  2290. si_socdevram_remap_isenb(si_t *sih)
  2291. {
  2292. si_info_t *sii = SI_INFO(sih);
  2293. uint origidx;
  2294. uint intr_val = 0;
  2295. sbsocramregs_t *regs;
  2296. bool wasup, remap = FALSE;
  2297. uint corerev;
  2298. uint32 extcinfo;
  2299. uint8 nb;
  2300. uint8 i;
  2301. uint32 bankidx, bankinfo;
  2302. /* Block ints and save current core */
  2303. INTR_OFF(sii, intr_val);
  2304. origidx = si_coreidx(sih);
  2305. /* Switch to SOCRAM core */
  2306. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  2307. goto done;
  2308. /* Get info for determining size */
  2309. if (!(wasup = si_iscoreup(sih)))
  2310. si_core_reset(sih, 0, 0);
  2311. corerev = si_corerev(sih);
  2312. if (corerev >= 16) {
  2313. extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
  2314. nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
  2315. for (i = 0; i < nb; i++) {
  2316. bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
  2317. W_REG(sii->osh, &regs->bankidx, bankidx);
  2318. bankinfo = R_REG(sii->osh, &regs->bankinfo);
  2319. if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) {
  2320. remap = TRUE;
  2321. break;
  2322. }
  2323. }
  2324. }
  2325. /* Return to previous state and core */
  2326. if (!wasup)
  2327. si_core_disable(sih, 0);
  2328. si_setcoreidx(sih, origidx);
  2329. done:
  2330. INTR_RESTORE(sii, intr_val);
  2331. return remap;
  2332. }
  2333. bool
  2334. si_socdevram_pkg(si_t *sih)
  2335. {
  2336. if (si_socdevram_size(sih) > 0)
  2337. return TRUE;
  2338. else
  2339. return FALSE;
  2340. }
  2341. uint32
  2342. si_socdevram_size(si_t *sih)
  2343. {
  2344. si_info_t *sii = SI_INFO(sih);
  2345. uint origidx;
  2346. uint intr_val = 0;
  2347. uint32 memsize = 0;
  2348. sbsocramregs_t *regs;
  2349. bool wasup;
  2350. uint corerev;
  2351. /* Block ints and save current core */
  2352. INTR_OFF(sii, intr_val);
  2353. origidx = si_coreidx(sih);
  2354. /* Switch to SOCRAM core */
  2355. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  2356. goto done;
  2357. /* Get info for determining size */
  2358. if (!(wasup = si_iscoreup(sih)))
  2359. si_core_reset(sih, 0, 0);
  2360. corerev = si_corerev(sih);
  2361. if (corerev >= 10) {
  2362. uint32 extcinfo;
  2363. uint8 nb;
  2364. uint8 i;
  2365. extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
  2366. nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
  2367. for (i = 0; i < nb; i++)
  2368. memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
  2369. }
  2370. /* Return to previous state and core */
  2371. if (!wasup)
  2372. si_core_disable(sih, 0);
  2373. si_setcoreidx(sih, origidx);
  2374. done:
  2375. INTR_RESTORE(sii, intr_val);
  2376. return memsize;
  2377. }
  2378. uint32
  2379. si_socdevram_remap_size(si_t *sih)
  2380. {
  2381. si_info_t *sii = SI_INFO(sih);
  2382. uint origidx;
  2383. uint intr_val = 0;
  2384. uint32 memsize = 0, banksz;
  2385. sbsocramregs_t *regs;
  2386. bool wasup;
  2387. uint corerev;
  2388. uint32 extcinfo;
  2389. uint8 nb;
  2390. uint8 i;
  2391. uint32 bankidx, bankinfo;
  2392. /* Block ints and save current core */
  2393. INTR_OFF(sii, intr_val);
  2394. origidx = si_coreidx(sih);
  2395. /* Switch to SOCRAM core */
  2396. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  2397. goto done;
  2398. /* Get info for determining size */
  2399. if (!(wasup = si_iscoreup(sih)))
  2400. si_core_reset(sih, 0, 0);
  2401. corerev = si_corerev(sih);
  2402. if (corerev >= 16) {
  2403. extcinfo = R_REG(sii->osh, &regs->extracoreinfo);
  2404. nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
  2405. /*
  2406. * FIX: A0 Issue: Max addressable is 512KB, instead 640KB
  2407. * Only four banks are accessible to ARM
  2408. */
  2409. if ((corerev == 16) && (nb == 5))
  2410. nb = 4;
  2411. for (i = 0; i < nb; i++) {
  2412. bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
  2413. W_REG(sii->osh, &regs->bankidx, bankidx);
  2414. bankinfo = R_REG(sii->osh, &regs->bankinfo);
  2415. if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) {
  2416. banksz = socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
  2417. memsize += banksz;
  2418. } else {
  2419. /* Account only consecutive banks for now */
  2420. break;
  2421. }
  2422. }
  2423. }
  2424. /* Return to previous state and core */
  2425. if (!wasup)
  2426. si_core_disable(sih, 0);
  2427. si_setcoreidx(sih, origidx);
  2428. done:
  2429. INTR_RESTORE(sii, intr_val);
  2430. return memsize;
  2431. }
  2432. /** Return the RAM size of the SOCRAM core */
  2433. uint32
  2434. si_socram_size(si_t *sih)
  2435. {
  2436. si_info_t *sii = SI_INFO(sih);
  2437. uint origidx;
  2438. uint intr_val = 0;
  2439. sbsocramregs_t *regs;
  2440. bool wasup;
  2441. uint corerev;
  2442. uint32 coreinfo;
  2443. uint memsize = 0;
  2444. /* Block ints and save current core */
  2445. INTR_OFF(sii, intr_val);
  2446. origidx = si_coreidx(sih);
  2447. /* Switch to SOCRAM core */
  2448. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  2449. goto done;
  2450. /* Get info for determining size */
  2451. if (!(wasup = si_iscoreup(sih)))
  2452. si_core_reset(sih, 0, 0);
  2453. corerev = si_corerev(sih);
  2454. coreinfo = R_REG(sii->osh, &regs->coreinfo);
  2455. /* Calculate size from coreinfo based on rev */
  2456. if (corerev == 0)
  2457. memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
  2458. else if (corerev < 3) {
  2459. memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
  2460. memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
  2461. } else if ((corerev <= 7) || (corerev == 12)) {
  2462. uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
  2463. uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
  2464. uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
  2465. if (lss != 0)
  2466. nb --;
  2467. memsize = nb * (1 << (bsz + SR_BSZ_BASE));
  2468. if (lss != 0)
  2469. memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
  2470. } else {
  2471. uint8 i;
  2472. uint nb;
  2473. /* length of SRAM Banks increased for corerev greater than 23 */
  2474. if (corerev >= 23) {
  2475. nb = (coreinfo & (SRCI_SRNB_MASK | SRCI_SRNB_MASK_EXT)) >> SRCI_SRNB_SHIFT;
  2476. } else {
  2477. nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
  2478. }
  2479. for (i = 0; i < nb; i++)
  2480. memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
  2481. }
  2482. /* Return to previous state and core */
  2483. if (!wasup)
  2484. si_core_disable(sih, 0);
  2485. si_setcoreidx(sih, origidx);
  2486. done:
  2487. INTR_RESTORE(sii, intr_val);
  2488. return memsize;
  2489. }
  2490. /** Return the TCM-RAM size of the ARMCR4 core. */
  2491. uint32
  2492. si_tcm_size(si_t *sih)
  2493. {
  2494. si_info_t *sii = SI_INFO(sih);
  2495. uint origidx;
  2496. uint intr_val = 0;
  2497. volatile uint8 *regs;
  2498. bool wasup;
  2499. uint32 corecap;
  2500. uint memsize = 0;
  2501. uint banku_size = 0;
  2502. uint32 nab = 0;
  2503. uint32 nbb = 0;
  2504. uint32 totb = 0;
  2505. uint32 bxinfo = 0;
  2506. uint32 idx = 0;
  2507. volatile uint32 *arm_cap_reg;
  2508. volatile uint32 *arm_bidx;
  2509. volatile uint32 *arm_binfo;
  2510. /* Block ints and save current core */
  2511. INTR_OFF(sii, intr_val);
  2512. origidx = si_coreidx(sih);
  2513. /* Switch to CR4 core */
  2514. if (!(regs = si_setcore(sih, ARMCR4_CORE_ID, 0)))
  2515. goto done;
  2516. /* Get info for determining size. If in reset, come out of reset,
  2517. * but remain in halt
  2518. */
  2519. if (!(wasup = si_iscoreup(sih)))
  2520. si_core_reset(sih, SICF_CPUHALT, SICF_CPUHALT);
  2521. arm_cap_reg = (volatile uint32 *)(regs + SI_CR4_CAP);
  2522. corecap = R_REG(sii->osh, arm_cap_reg);
  2523. nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
  2524. nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
  2525. totb = nab + nbb;
  2526. arm_bidx = (volatile uint32 *)(regs + SI_CR4_BANKIDX);
  2527. arm_binfo = (volatile uint32 *)(regs + SI_CR4_BANKINFO);
  2528. for (idx = 0; idx < totb; idx++) {
  2529. W_REG(sii->osh, arm_bidx, idx);
  2530. bxinfo = R_REG(sii->osh, arm_binfo);
  2531. if (bxinfo & ARMCR4_BUNITSZ_MASK) {
  2532. banku_size = ARMCR4_BSZ_1K;
  2533. } else {
  2534. banku_size = ARMCR4_BSZ_8K;
  2535. }
  2536. memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * banku_size;
  2537. }
  2538. /* Return to previous state and core */
  2539. if (!wasup)
  2540. si_core_disable(sih, 0);
  2541. si_setcoreidx(sih, origidx);
  2542. done:
  2543. INTR_RESTORE(sii, intr_val);
  2544. return memsize;
  2545. }
  2546. bool
  2547. si_has_flops(si_t *sih)
  2548. {
  2549. uint origidx, cr4_rev;
  2550. /* Find out CR4 core revision */
  2551. origidx = si_coreidx(sih);
  2552. if (si_setcore(sih, ARMCR4_CORE_ID, 0)) {
  2553. cr4_rev = si_corerev(sih);
  2554. si_setcoreidx(sih, origidx);
  2555. if (cr4_rev == 1 || cr4_rev >= 3)
  2556. return TRUE;
  2557. }
  2558. return FALSE;
  2559. }
  2560. uint32
  2561. si_socram_srmem_size(si_t *sih)
  2562. {
  2563. si_info_t *sii = SI_INFO(sih);
  2564. uint origidx;
  2565. uint intr_val = 0;
  2566. sbsocramregs_t *regs;
  2567. bool wasup;
  2568. uint corerev;
  2569. uint32 coreinfo;
  2570. uint memsize = 0;
  2571. if (CHIPID(sih->chip) == BCM43430_CHIP_ID ||
  2572. CHIPID(sih->chip) == BCM43018_CHIP_ID) {
  2573. return (64 * 1024);
  2574. }
  2575. /* Block ints and save current core */
  2576. INTR_OFF(sii, intr_val);
  2577. origidx = si_coreidx(sih);
  2578. /* Switch to SOCRAM core */
  2579. if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
  2580. goto done;
  2581. /* Get info for determining size */
  2582. if (!(wasup = si_iscoreup(sih)))
  2583. si_core_reset(sih, 0, 0);
  2584. corerev = si_corerev(sih);
  2585. coreinfo = R_REG(sii->osh, &regs->coreinfo);
  2586. /* Calculate size from coreinfo based on rev */
  2587. if (corerev >= 16) {
  2588. uint8 i;
  2589. uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
  2590. for (i = 0; i < nb; i++) {
  2591. W_REG(sii->osh, &regs->bankidx, i);
  2592. if (R_REG(sii->osh, &regs->bankinfo) & SOCRAM_BANKINFO_RETNTRAM_MASK)
  2593. memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
  2594. }
  2595. }
  2596. /* Return to previous state and core */
  2597. if (!wasup)
  2598. si_core_disable(sih, 0);
  2599. si_setcoreidx(sih, origidx);
  2600. done:
  2601. INTR_RESTORE(sii, intr_val);
  2602. return memsize;
  2603. }
  2604. #if !defined(_CFEZ_) || defined(CFG_WL)
  2605. void
  2606. si_btcgpiowar(si_t *sih)
  2607. {
  2608. si_info_t *sii = SI_INFO(sih);
  2609. uint origidx;
  2610. uint intr_val = 0;
  2611. chipcregs_t *cc;
  2612. /* Make sure that there is ChipCommon core present &&
  2613. * UART_TX is strapped to 1
  2614. */
  2615. if (!(sih->cccaps & CC_CAP_UARTGPIO))
  2616. return;
  2617. /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */
  2618. INTR_OFF(sii, intr_val);
  2619. origidx = si_coreidx(sih);
  2620. cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
  2621. ASSERT(cc != NULL);
  2622. W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04);
  2623. /* restore the original index */
  2624. si_setcoreidx(sih, origidx);
  2625. INTR_RESTORE(sii, intr_val);
  2626. }
  2627. void
  2628. si_chipcontrl_restore(si_t *sih, uint32 val)
  2629. {
  2630. si_info_t *sii = SI_INFO(sih);
  2631. chipcregs_t *cc;
  2632. uint origidx = si_coreidx(sih);
  2633. if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
  2634. SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
  2635. return;
  2636. }
  2637. W_REG(sii->osh, &cc->chipcontrol, val);
  2638. si_setcoreidx(sih, origidx);
  2639. }
  2640. uint32
  2641. si_chipcontrl_read(si_t *sih)
  2642. {
  2643. si_info_t *sii = SI_INFO(sih);
  2644. chipcregs_t *cc;
  2645. uint origidx = si_coreidx(sih);
  2646. uint32 val;
  2647. if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
  2648. SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
  2649. return -1;
  2650. }
  2651. val = R_REG(sii->osh, &cc->chipcontrol);
  2652. si_setcoreidx(sih, origidx);
  2653. return val;
  2654. }
  2655. /** switch muxed pins, on: SROM, off: FEMCTRL. Called for a family of ac chips, not just 4360. */
  2656. void
  2657. si_chipcontrl_srom4360(si_t *sih, bool on)
  2658. {
  2659. si_info_t *sii = SI_INFO(sih);
  2660. chipcregs_t *cc;
  2661. uint origidx = si_coreidx(sih);
  2662. uint32 val;
  2663. if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
  2664. SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
  2665. return;
  2666. }
  2667. val = R_REG(sii->osh, &cc->chipcontrol);
  2668. if (on) {
  2669. val &= ~(CCTRL4360_SECI_MODE |
  2670. CCTRL4360_BTSWCTRL_MODE |
  2671. CCTRL4360_EXTRA_FEMCTRL_MODE |
  2672. CCTRL4360_BT_LGCY_MODE |
  2673. CCTRL4360_CORE2FEMCTRL4_ON);
  2674. W_REG(sii->osh, &cc->chipcontrol, val);
  2675. } else {
  2676. }
  2677. si_setcoreidx(sih, origidx);
  2678. }
  2679. /**
  2680. * The SROM clock is derived from the backplane clock. 4365 (200Mhz) and 43684 (240Mhz) have a fast
  2681. * backplane clock that requires a higher-than-POR-default clock divisor ratio for the SROM clock.
  2682. */
  2683. void
  2684. si_srom_clk_set(si_t *sih)
  2685. {
  2686. si_info_t *sii = SI_INFO(sih);
  2687. chipcregs_t *cc;
  2688. uint origidx = si_coreidx(sih);
  2689. uint32 val;
  2690. uint32 divisor = 1;
  2691. if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
  2692. SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
  2693. return;
  2694. }
  2695. val = R_REG(sii->osh, &cc->clkdiv2);
  2696. if (BCM4365_CHIP(sih->chip)) {
  2697. divisor = CLKD2_SROMDIV_192; /* divide 200 by 192 -> SPROM clock ~ 1.04Mhz */
  2698. } else {
  2699. ASSERT(0);
  2700. }
  2701. W_REG(sii->osh, &cc->clkdiv2, ((val & ~CLKD2_SROM) | divisor));
  2702. si_setcoreidx(sih, origidx);
  2703. }
  2704. #endif // endif
  2705. void
  2706. si_pmu_avb_clk_set(si_t *sih, osl_t *osh, bool set_flag)
  2707. {
  2708. }
  2709. void
  2710. si_btc_enable_chipcontrol(si_t *sih)
  2711. {
  2712. si_info_t *sii = SI_INFO(sih);
  2713. chipcregs_t *cc;
  2714. uint origidx = si_coreidx(sih);
  2715. if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
  2716. SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
  2717. return;
  2718. }
  2719. /* BT fix */
  2720. W_REG(sii->osh, &cc->chipcontrol,
  2721. R_REG(sii->osh, &cc->chipcontrol) | CC_BTCOEX_EN_MASK);
  2722. si_setcoreidx(sih, origidx);
  2723. }
  2724. /** cache device removed state */
  2725. void si_set_device_removed(si_t *sih, bool status)
  2726. {
  2727. si_info_t *sii = SI_INFO(sih);
  2728. sii->device_removed = status;
  2729. }
  2730. /** check if the device is removed */
  2731. bool
  2732. si_deviceremoved(si_t *sih)
  2733. {
  2734. uint32 w;
  2735. si_info_t *sii = SI_INFO(sih);
  2736. if (sii->device_removed) {
  2737. return TRUE;
  2738. }
  2739. switch (BUSTYPE(sih->bustype)) {
  2740. case PCI_BUS:
  2741. ASSERT(SI_INFO(sih)->osh != NULL);
  2742. w = OSL_PCI_READ_CONFIG(SI_INFO(sih)->osh, PCI_CFG_VID, sizeof(uint32));
  2743. if ((w & 0xFFFF) != VENDOR_BROADCOM)
  2744. return TRUE;
  2745. break;
  2746. }
  2747. return FALSE;
  2748. }
  2749. bool
  2750. si_is_warmboot(void)
  2751. {
  2752. #ifdef BCMULP
  2753. return (boot_type == WARM_BOOT);
  2754. #else
  2755. return FALSE;
  2756. #endif // endif
  2757. }
  2758. bool
  2759. si_is_sprom_available(si_t *sih)
  2760. {
  2761. if (CCREV(sih->ccrev) >= 31) {
  2762. si_info_t *sii;
  2763. uint origidx;
  2764. chipcregs_t *cc;
  2765. uint32 sromctrl;
  2766. if ((sih->cccaps & CC_CAP_SROM) == 0)
  2767. return FALSE;
  2768. sii = SI_INFO(sih);
  2769. origidx = sii->curidx;
  2770. cc = si_setcoreidx(sih, SI_CC_IDX);
  2771. ASSERT(cc);
  2772. sromctrl = R_REG(sii->osh, &cc->sromcontrol);
  2773. si_setcoreidx(sih, origidx);
  2774. return (sromctrl & SRC_PRESENT);
  2775. }
  2776. switch (CHIPID(sih->chip)) {
  2777. case BCM43018_CHIP_ID:
  2778. case BCM43430_CHIP_ID:
  2779. return FALSE;
  2780. case BCM4335_CHIP_ID:
  2781. CASE_BCM4345_CHIP:
  2782. return ((sih->chipst & CST4335_SPROM_MASK) &&
  2783. !(sih->chipst & CST4335_SFLASH_MASK));
  2784. case BCM4349_CHIP_GRPID:
  2785. return (sih->chipst & CST4349_SPROM_PRESENT) != 0;
  2786. case BCM53573_CHIP_GRPID:
  2787. return FALSE; /* SPROM PRESENT is not defined for 53573 as of now */
  2788. case BCM4364_CHIP_ID:
  2789. return (sih->chipst & CST4364_SPROM_PRESENT) != 0;
  2790. case BCM4369_CHIP_GRPID:
  2791. if (CHIPREV(sih->chiprev) == 0) {
  2792. /* WAR for 4369a0: HW4369-1729. no sprom, default to otp always. */
  2793. return 0;
  2794. } else {
  2795. return (sih->chipst & CST4369_SPROM_PRESENT) != 0;
  2796. }
  2797. #ifdef CHIPS_CUSTOMER_HW6
  2798. case BCM4368_CHIP_ID:
  2799. return FALSE;
  2800. #endif /* CHIPS_CUSTOMER_HW6 */
  2801. case BCM4347_CHIP_GRPID:
  2802. return (sih->chipst & CST4347_SPROM_PRESENT) != 0;
  2803. break;
  2804. case BCM4350_CHIP_ID:
  2805. case BCM4354_CHIP_ID:
  2806. case BCM43556_CHIP_ID:
  2807. case BCM43558_CHIP_ID:
  2808. case BCM43566_CHIP_ID:
  2809. case BCM43568_CHIP_ID:
  2810. case BCM43569_CHIP_ID:
  2811. case BCM43570_CHIP_ID:
  2812. case BCM4358_CHIP_ID:
  2813. return (sih->chipst & CST4350_SPROM_PRESENT) != 0;
  2814. CASE_BCM43602_CHIP:
  2815. return (sih->chipst & CST43602_SPROM_PRESENT) != 0;
  2816. case BCM43131_CHIP_ID:
  2817. case BCM43217_CHIP_ID:
  2818. case BCM43428_CHIP_ID:
  2819. return (sih->chipst & CST43228_OTP_PRESENT) != CST43228_OTP_PRESENT;
  2820. case BCM4373_CHIP_ID:
  2821. case BCM43012_CHIP_ID:
  2822. return FALSE;
  2823. default:
  2824. return TRUE;
  2825. }
  2826. }
  2827. uint32 si_get_sromctl(si_t *sih)
  2828. {
  2829. chipcregs_t *cc;
  2830. uint origidx = si_coreidx(sih);
  2831. uint32 sromctl;
  2832. osl_t *osh = si_osh(sih);
  2833. cc = si_setcoreidx(sih, SI_CC_IDX);
  2834. ASSERT((uintptr)cc);
  2835. sromctl = R_REG(osh, &cc->sromcontrol);
  2836. /* return to the original core */
  2837. si_setcoreidx(sih, origidx);
  2838. return sromctl;
  2839. }
  2840. int si_set_sromctl(si_t *sih, uint32 value)
  2841. {
  2842. chipcregs_t *cc;
  2843. uint origidx = si_coreidx(sih);
  2844. osl_t *osh = si_osh(sih);
  2845. int ret = BCME_OK;
  2846. cc = si_setcoreidx(sih, SI_CC_IDX);
  2847. ASSERT((uintptr)cc);
  2848. /* get chipcommon rev */
  2849. if (si_corerev(sih) >= 32) {
  2850. /* SpromCtrl is only accessible if CoreCapabilities.SpromSupported and
  2851. * SpromPresent is 1.
  2852. */
  2853. if ((R_REG(osh, &cc->capabilities) & CC_CAP_SROM) != 0 &&
  2854. (R_REG(osh, &cc->sromcontrol) & SRC_PRESENT)) {
  2855. W_REG(osh, &cc->sromcontrol, value);
  2856. } else {
  2857. ret = BCME_NODEVICE;
  2858. }
  2859. } else {
  2860. ret = BCME_UNSUPPORTED;
  2861. }
  2862. /* return to the original core */
  2863. si_setcoreidx(sih, origidx);
  2864. return ret;
  2865. }
  2866. uint
  2867. si_core_wrapperreg(si_t *sih, uint32 coreidx, uint32 offset, uint32 mask, uint32 val)
  2868. {
  2869. uint origidx, intr_val = 0;
  2870. uint ret_val;
  2871. si_info_t *sii = SI_INFO(sih);
  2872. origidx = si_coreidx(sih);
  2873. INTR_OFF(sii, intr_val);
  2874. si_setcoreidx(sih, coreidx);
  2875. ret_val = si_wrapperreg(sih, offset, mask, val);
  2876. /* return to the original core */
  2877. si_setcoreidx(sih, origidx);
  2878. INTR_RESTORE(sii, intr_val);
  2879. return ret_val;
  2880. }
  2881. /* cleanup the timer from the host when ARM is been halted
  2882. * without a chance for ARM cleanup its resources
  2883. * If left not cleanup, Intr from a software timer can still
  2884. * request HT clk when ARM is halted.
  2885. */
  2886. uint32
  2887. si_pmu_res_req_timer_clr(si_t *sih)
  2888. {
  2889. uint32 mask;
  2890. mask = PRRT_REQ_ACTIVE | PRRT_INTEN | PRRT_HT_REQ;
  2891. mask <<= 14;
  2892. /* clear mask bits */
  2893. pmu_corereg(sih, SI_CC_IDX, res_req_timer, mask, 0);
  2894. /* readback to ensure write completes */
  2895. return pmu_corereg(sih, SI_CC_IDX, res_req_timer, 0, 0);
  2896. }
  2897. /** turn on/off rfldo */
  2898. void
  2899. si_pmu_rfldo(si_t *sih, bool on)
  2900. {
  2901. }
  2902. /* Caller of this function should make sure is on PCIE core
  2903. * Used in pciedev.c.
  2904. */
  2905. void
  2906. si_pcie_disable_oobselltr(si_t *sih)
  2907. {
  2908. ASSERT(si_coreid(sih) == PCIE2_CORE_ID);
  2909. if (PCIECOREREV(sih->buscorerev) >= 23)
  2910. si_wrapperreg(sih, AI_OOBSELIND74, ~0, 0);
  2911. else
  2912. si_wrapperreg(sih, AI_OOBSELIND30, ~0, 0);
  2913. }
  2914. void
  2915. si_pcie_ltr_war(si_t *sih)
  2916. {
  2917. }
  2918. void
  2919. si_pcie_hw_LTR_war(si_t *sih)
  2920. {
  2921. }
  2922. void
  2923. si_pciedev_reg_pm_clk_period(si_t *sih)
  2924. {
  2925. }
  2926. void
  2927. si_pciedev_crwlpciegen2(si_t *sih)
  2928. {
  2929. }
  2930. void
  2931. si_pcie_prep_D3(si_t *sih, bool enter_D3)
  2932. {
  2933. }
  2934. #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
  2935. uint32
  2936. si_clear_backplane_to_per_core(si_t *sih, uint coreid, uint coreunit, void * wrap)
  2937. {
  2938. if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  2939. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS)) {
  2940. return ai_clear_backplane_to_per_core(sih, coreid, coreunit, wrap);
  2941. }
  2942. return AXI_WRAP_STS_NONE;
  2943. }
  2944. #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
  2945. uint32
  2946. si_clear_backplane_to(si_t *sih)
  2947. {
  2948. if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
  2949. (CHIPTYPE(sih->socitype) == SOCI_DVTBUS)) {
  2950. return ai_clear_backplane_to(sih);
  2951. }
  2952. return 0;
  2953. }
  2954. void
  2955. si_update_backplane_timeouts(si_t *sih, bool enable, uint32 timeout_exp, uint32 cid)
  2956. {
  2957. #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
  2958. /* Enable only for AXI */
  2959. if (CHIPTYPE(sih->socitype) != SOCI_AI) {
  2960. return;
  2961. }
  2962. ai_update_backplane_timeouts(sih, enable, timeout_exp, cid);
  2963. #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
  2964. }
  2965. /*
  2966. * This routine adds the AXI timeouts for
  2967. * chipcommon, pcie and ARM slave wrappers
  2968. */
  2969. void
  2970. si_slave_wrapper_add(si_t *sih)
  2971. {
  2972. #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
  2973. uint32 axi_to = 0;
  2974. /* Enable only for AXI */
  2975. if ((CHIPTYPE(sih->socitype) != SOCI_AI) &&
  2976. (CHIPTYPE(sih->socitype) != SOCI_DVTBUS)) {
  2977. return;
  2978. }
  2979. if (CHIPID(sih->chip) == BCM4345_CHIP_ID && CHIPREV(sih->chiprev) >= 6) {
  2980. si_info_t *sii = SI_INFO(sih);
  2981. int wrapper_idx = (int)sii->axi_num_wrappers - 1;
  2982. ASSERT(wrapper_idx >= 0); /* axi_wrapper[] not initialised */
  2983. do {
  2984. if (sii->axi_wrapper[wrapper_idx].wrapper_type == AI_SLAVE_WRAPPER &&
  2985. sii->axi_wrapper[wrapper_idx].cid == 0xfff) {
  2986. sii->axi_wrapper[wrapper_idx].wrapper_addr = 0x1810b000;
  2987. break;
  2988. }
  2989. } while (wrapper_idx-- > 0);
  2990. ASSERT(wrapper_idx >= 0); /* all addresses valid for the chiprev under test */
  2991. }
  2992. if (BCM4347_CHIP(sih->chip)) {
  2993. axi_to = AXI_TO_VAL_4347;
  2994. }
  2995. else {
  2996. axi_to = AXI_TO_VAL;
  2997. }
  2998. /* All required slave wrappers are added in ai_scan */
  2999. ai_update_backplane_timeouts(sih, TRUE, axi_to, 0);
  3000. #ifdef DISABLE_PCIE2_AXI_TIMEOUT
  3001. ai_update_backplane_timeouts(sih, FALSE, 0, PCIE_CORE_ID);
  3002. ai_update_backplane_timeouts(sih, FALSE, 0, PCIE2_CORE_ID);
  3003. #endif // endif
  3004. #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
  3005. }
  3006. void
  3007. si_pll_sr_reinit(si_t *sih)
  3008. {
  3009. }
  3010. /* Programming d11 core oob settings for 4364
  3011. * WARs for HW4364-237 and HW4364-166
  3012. */
  3013. void
  3014. si_config_4364_d11_oob(si_t *sih, uint coreid)
  3015. {
  3016. uint save_idx;
  3017. save_idx = si_coreidx(sih);
  3018. si_setcore(sih, coreid, 0);
  3019. si_wrapperreg(sih, AI_OOBSELINC30, ~0, 0x81828180);
  3020. si_wrapperreg(sih, AI_OOBSELINC74, ~0, 0x87868183);
  3021. si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, 0x84858484);
  3022. si_setcore(sih, coreid, 1);
  3023. si_wrapperreg(sih, AI_OOBSELINC30, ~0, 0x81828180);
  3024. si_wrapperreg(sih, AI_OOBSELINC74, ~0, 0x87868184);
  3025. si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, 0x84868484);
  3026. si_setcoreidx(sih, save_idx);
  3027. }
  3028. void
  3029. si_pll_closeloop(si_t *sih)
  3030. {
  3031. #if defined(SAVERESTORE)
  3032. uint32 data;
  3033. /* disable PLL open loop operation */
  3034. switch (CHIPID(sih->chip)) {
  3035. #ifdef SAVERESTORE
  3036. case BCM43018_CHIP_ID:
  3037. case BCM43430_CHIP_ID:
  3038. if (SR_ENAB() && sr_isenab(sih)) {
  3039. /* read back the pll openloop state */
  3040. data = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8, 0, 0);
  3041. /* current mode is openloop (possible POR) */
  3042. if ((data & PMU1_PLLCTL8_OPENLOOP_MASK) != 0) {
  3043. si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8,
  3044. PMU1_PLLCTL8_OPENLOOP_MASK, 0);
  3045. si_pmu_pllupd(sih);
  3046. }
  3047. }
  3048. break;
  3049. #endif /* SAVERESTORE */
  3050. case BCM4347_CHIP_GRPID:
  3051. case BCM4369_CHIP_GRPID:
  3052. si_pmu_chipcontrol(sih, PMU_CHIPCTL1,
  3053. PMU_CC1_ENABLE_CLOSED_LOOP_MASK, PMU_CC1_ENABLE_CLOSED_LOOP);
  3054. break;
  3055. default:
  3056. /* any unsupported chip bail */
  3057. return;
  3058. }
  3059. #endif // endif
  3060. }
  3061. #if defined(BCMSRPWR) && !defined(BCMSRPWR_DISABLED)
  3062. bool _bcmsrpwr = TRUE;
  3063. #else
  3064. bool _bcmsrpwr = FALSE;
  3065. #endif // endif
  3066. #define PWRREQ_OFFSET(sih) OFFSETOF(chipcregs_t, powerctl)
  3067. static void
  3068. si_corereg_pciefast_write(si_t *sih, uint regoff, uint val)
  3069. {
  3070. volatile uint32 *r = NULL;
  3071. si_info_t *sii = SI_INFO(sih);
  3072. ASSERT((BUSTYPE(sih->bustype) == PCI_BUS));
  3073. r = (volatile uint32 *)((volatile char *)sii->curmap +
  3074. PCI_16KB0_PCIREGS_OFFSET + regoff);
  3075. W_REG(sii->osh, r, val);
  3076. }
  3077. static uint
  3078. si_corereg_pciefast_read(si_t *sih, uint regoff)
  3079. {
  3080. volatile uint32 *r = NULL;
  3081. si_info_t *sii = SI_INFO(sih);
  3082. ASSERT((BUSTYPE(sih->bustype) == PCI_BUS));
  3083. r = (volatile uint32 *)((volatile char *)sii->curmap +
  3084. PCI_16KB0_PCIREGS_OFFSET + regoff);
  3085. return R_REG(sii->osh, r);
  3086. }
  3087. uint32
  3088. si_srpwr_request(si_t *sih, uint32 mask, uint32 val)
  3089. {
  3090. uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
  3091. OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
  3092. uint32 mask2 = mask;
  3093. uint32 val2 = val;
  3094. volatile uint32 *fast_srpwr_addr = (volatile uint32 *)((uintptr)SI_ENUM_BASE(sih)
  3095. + (uintptr)offset);
  3096. if (mask || val) {
  3097. mask <<= SRPWR_REQON_SHIFT;
  3098. val <<= SRPWR_REQON_SHIFT;
  3099. /* Return if requested power request is already set */
  3100. if (BUSTYPE(sih->bustype) == SI_BUS) {
  3101. r = R_REG(OSH_NULL, fast_srpwr_addr);
  3102. } else {
  3103. r = si_corereg_pciefast_read(sih, offset);
  3104. }
  3105. if ((r & mask) == val) {
  3106. return r;
  3107. }
  3108. r = (r & ~mask) | val;
  3109. if (BUSTYPE(sih->bustype) == SI_BUS) {
  3110. W_REG(OSH_NULL, fast_srpwr_addr, r);
  3111. r = R_REG(OSH_NULL, fast_srpwr_addr);
  3112. } else {
  3113. si_corereg_pciefast_write(sih, offset, r);
  3114. r = si_corereg_pciefast_read(sih, offset);
  3115. }
  3116. if (val2) {
  3117. if ((r & (mask2 << SRPWR_STATUS_SHIFT)) ==
  3118. (val2 << SRPWR_STATUS_SHIFT)) {
  3119. return r;
  3120. }
  3121. si_srpwr_stat_spinwait(sih, mask2, val2);
  3122. }
  3123. } else {
  3124. if (BUSTYPE(sih->bustype) == SI_BUS) {
  3125. r = R_REG(OSH_NULL, fast_srpwr_addr);
  3126. } else {
  3127. r = si_corereg_pciefast_read(sih, offset);
  3128. }
  3129. }
  3130. return r;
  3131. }
  3132. uint32
  3133. si_srpwr_stat_spinwait(si_t *sih, uint32 mask, uint32 val)
  3134. {
  3135. uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
  3136. OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
  3137. volatile uint32 *fast_srpwr_addr = (volatile uint32 *)((uintptr)SI_ENUM_BASE(sih)
  3138. + (uintptr)offset);
  3139. ASSERT(mask);
  3140. ASSERT(val);
  3141. /* spinwait on pwrstatus */
  3142. mask <<= SRPWR_STATUS_SHIFT;
  3143. val <<= SRPWR_STATUS_SHIFT;
  3144. if (BUSTYPE(sih->bustype) == SI_BUS) {
  3145. SPINWAIT(((R_REG(OSH_NULL, fast_srpwr_addr) & mask) != val),
  3146. PMU_MAX_TRANSITION_DLY);
  3147. r = R_REG(OSH_NULL, fast_srpwr_addr) & mask;
  3148. ASSERT(r == val);
  3149. } else {
  3150. SPINWAIT(((si_corereg_pciefast_read(sih, offset) & mask) != val),
  3151. PMU_MAX_TRANSITION_DLY);
  3152. r = si_corereg_pciefast_read(sih, offset) & mask;
  3153. ASSERT(r == val);
  3154. }
  3155. r = (r >> SRPWR_STATUS_SHIFT) & SRPWR_DMN_ALL_MASK(sih);
  3156. return r;
  3157. }
  3158. uint32
  3159. si_srpwr_stat(si_t *sih)
  3160. {
  3161. uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
  3162. OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
  3163. uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
  3164. if (BUSTYPE(sih->bustype) == SI_BUS) {
  3165. r = si_corereg(sih, cidx, offset, 0, 0);
  3166. } else {
  3167. r = si_corereg_pciefast_read(sih, offset);
  3168. }
  3169. r = (r >> SRPWR_STATUS_SHIFT) & SRPWR_DMN_ALL_MASK(sih);
  3170. return r;
  3171. }
  3172. uint32
  3173. si_srpwr_domain(si_t *sih)
  3174. {
  3175. uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
  3176. OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
  3177. uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
  3178. if (BUSTYPE(sih->bustype) == SI_BUS) {
  3179. r = si_corereg(sih, cidx, offset, 0, 0);
  3180. } else {
  3181. r = si_corereg_pciefast_read(sih, offset);
  3182. }
  3183. r = (r >> SRPWR_DMN_ID_SHIFT) & SRPWR_DMN_ID_MASK;
  3184. return r;
  3185. }
  3186. uint32
  3187. si_srpwr_domain_all_mask(si_t *sih)
  3188. {
  3189. uint32 mask = SRPWR_DMN0_PCIE_MASK |
  3190. SRPWR_DMN1_ARMBPSD_MASK |
  3191. SRPWR_DMN2_MACAUX_MASK |
  3192. SRPWR_DMN3_MACMAIN_MASK;
  3193. if (si_scan_core_present(sih)) {
  3194. mask |= SRPWR_DMN4_MACSCAN_MASK;
  3195. }
  3196. return mask;
  3197. }
  3198. /* Utility API to read/write the raw registers with absolute address.
  3199. * This function can be invoked from either FW or host driver.
  3200. */
  3201. uint32
  3202. si_raw_reg(si_t *sih, uint32 reg, uint32 val, uint32 wrire_req)
  3203. {
  3204. si_info_t *sii = SI_INFO(sih);
  3205. uint32 address_space = reg & ~0xFFF;
  3206. volatile uint32 * addr = (void*)(uintptr)(reg);
  3207. uint32 prev_value = 0;
  3208. uint32 cfg_reg = 0;
  3209. if (sii == NULL) {
  3210. return 0;
  3211. }
  3212. /* No need to translate the absolute address on SI bus */
  3213. if (BUSTYPE(sih->bustype) == SI_BUS) {
  3214. goto skip_cfg;
  3215. }
  3216. /* This API supports only the PCI host interface */
  3217. if (BUSTYPE(sih->bustype) != PCI_BUS) {
  3218. return ID32_INVALID;
  3219. }
  3220. if (PCIE_GEN2(sii)) {
  3221. /* Use BAR0 Secondary window is PCIe Gen2.
  3222. * Set the secondary BAR0 Window to current register of interest
  3223. */
  3224. addr = (volatile uint32*)(((volatile uint8*)sii->curmap) +
  3225. PCI_SEC_BAR0_WIN_OFFSET + (reg & 0xfff));
  3226. cfg_reg = PCIE2_BAR0_CORE2_WIN;
  3227. } else {
  3228. /* PCIe Gen1 do not have secondary BAR0 window.
  3229. * reuse the BAR0 WIN2
  3230. */
  3231. addr = (volatile uint32*)(((volatile uint8*)sii->curmap) +
  3232. PCI_BAR0_WIN2_OFFSET + (reg & 0xfff));
  3233. cfg_reg = PCI_BAR0_WIN2;
  3234. }
  3235. prev_value = OSL_PCI_READ_CONFIG(sii->osh, cfg_reg, 4);
  3236. if (prev_value != address_space) {
  3237. OSL_PCI_WRITE_CONFIG(sii->osh, cfg_reg,
  3238. sizeof(uint32), address_space);
  3239. } else {
  3240. prev_value = 0;
  3241. }
  3242. skip_cfg:
  3243. if (wrire_req) {
  3244. W_REG(sii->osh, addr, val);
  3245. } else {
  3246. val = R_REG(sii->osh, addr);
  3247. }
  3248. if (prev_value) {
  3249. /* Restore BAR0 WIN2 for PCIE GEN1 devices */
  3250. OSL_PCI_WRITE_CONFIG(sii->osh,
  3251. cfg_reg, sizeof(uint32), prev_value);
  3252. }
  3253. return val;
  3254. }
  3255. uint8
  3256. si_lhl_ps_mode(si_t *sih)
  3257. {
  3258. si_info_t *sii = SI_INFO(sih);
  3259. return sii->lhl_ps_mode;
  3260. }
  3261. bool
  3262. BCMRAMFN(si_scan_core_present)(si_t *sih)
  3263. {
  3264. return ((si_numcoreunits(sih, D11_CORE_ID) >= 2) &&
  3265. (si_numcoreunits(sih, SR_CORE_ID) > 4));
  3266. }