| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819 |
- /*
- * Misc utility routines for accessing chip-specific features
- * of the SiliconBackplane-based Broadcom chips.
- *
- * Portions of this code are copyright (c) 2020 Cypress Semiconductor Corporation
- *
- * Copyright (C) 1999-2020, Broadcom Corporation
- *
- * Unless you and Broadcom execute a separate written software license
- * agreement governing use of this software, this software is licensed to you
- * under the terms of the GNU General Public License version 2 (the "GPL"),
- * available at http://www.broadcom.com/licenses/GPLv2.php, with the
- * following added to such license:
- *
- * As a special exception, the copyright holders of this software give you
- * permission to link this software with independent modules, and to copy and
- * distribute the resulting executable under terms of your choice, provided that
- * you also meet, for each linked independent module, the terms and conditions of
- * the license of that module. An independent module is a module which is not
- * derived from this software. The special exception does not apply to any
- * modifications of the software.
- *
- * Notwithstanding the above, under no circumstances may you combine this
- * software in any way with any other Broadcom software provided under a license
- * other than the GPL, without Broadcom's express prior written consent.
- *
- *
- * <<Broadcom-WL-IPTag/Open:>>
- *
- * $Id: siutils.c 701025 2017-05-23 10:23:52Z $
- */
- #include <bcm_cfg.h>
- #include <typedefs.h>
- #include <bcmdefs.h>
- #include <osl.h>
- #include <bcmutils.h>
- #include <siutils.h>
- #include <bcmdevs.h>
- #include <hndsoc.h>
- #include <sbchipc.h>
- #include <sbgci.h>
- #ifndef BCMSDIO
- #include <pcie_core.h>
- #endif // endif
- #ifdef BCMPCIEDEV
- #include <pciedev.h>
- #endif /* BCMPCIEDEV */
- #include <pcicfg.h>
- #include <sbpcmcia.h>
- #include <sbsysmem.h>
- #include <sbsocram.h>
- #ifdef BCMSDIO
- #include <bcmsdh.h>
- #include <sdio.h>
- #include <sbsdio.h>
- #include <sbhnddma.h>
- #include <sbsdpcmdev.h>
- #include <bcmsdpcm.h>
- #endif /* BCMSDIO */
- #include <hndpmu.h>
- #ifdef BCMSPI
- #include <spid.h>
- #endif /* BCMSPI */
- #ifdef BCM_SDRBL
- #include <hndcpu.h>
- #endif /* BCM_SDRBL */
- #ifdef HNDGCI
- #include <hndgci.h>
- #endif /* HNDGCI */
- #ifdef WLGCIMBHLR
- #include <hnd_gci.h>
- #endif /* WLGCIMBHLR */
- #ifdef BCMULP
- #include <ulp.h>
- #endif /* BCMULP */
- #include <hndlhl.h>
- #include <lpflags.h>
- #include "siutils_priv.h"
- #ifdef SECI_UART
- /* Defines the set of GPIOs to be used for SECI UART if not specified in NVRAM */
- /* For further details on each ppin functionality please refer to PINMUX table in
- * Top level architecture of BCMXXXX Chip
- */
- #define DEFAULT_SECI_UART_PINMUX 0x08090a0b
- #define DEFAULT_SECI_UART_PINMUX_43430 0x0102
- static bool force_seci_clk = 0;
- #endif /* SECI_UART */
- #define XTAL_FREQ_26000KHZ 26000
- /**
- * A set of PMU registers is clocked in the ILP domain, which has an implication on register write
- * behavior: if such a register is written, it takes multiple ILP clocks for the PMU block to absorb
- * the write. During that time the 'SlowWritePending' bit in the PMUStatus register is set.
- */
- #define PMUREGS_ILP_SENSITIVE(regoff) \
- ((regoff) == OFFSETOF(pmuregs_t, pmutimer) || \
- (regoff) == OFFSETOF(pmuregs_t, pmuwatchdog) || \
- (regoff) == OFFSETOF(pmuregs_t, res_req_timer))
- #define CHIPCREGS_ILP_SENSITIVE(regoff) \
- ((regoff) == OFFSETOF(chipcregs_t, pmutimer) || \
- (regoff) == OFFSETOF(chipcregs_t, pmuwatchdog) || \
- (regoff) == OFFSETOF(chipcregs_t, res_req_timer))
- #define GCI_FEM_CTRL_WAR 0x11111111
- #ifndef AXI_TO_VAL
- #define AXI_TO_VAL 19
- #endif /* AXI_TO_VAL */
- #ifndef AXI_TO_VAL_4347
- /*
- * Increase BP timeout for fast clock and short PCIe timeouts
- * New timeout: 2 ** 25 cycles
- */
- #define AXI_TO_VAL_4347 25
- #endif /* AXI_TO_VAL_4347 */
- /* local prototypes */
- static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
- uint bustype, void *sdh, char **vars, uint *varsz);
- static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh);
- static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
- uint *origidx, volatile void *regs);
- static bool si_pmu_is_ilp_sensitive(uint32 idx, uint regoff);
- /* global variable to indicate reservation/release of gpio's */
- static uint32 si_gpioreservation = 0;
- /* global flag to prevent shared resources from being initialized multiple times in si_attach() */
- static bool si_onetimeinit = FALSE;
- #ifdef SR_DEBUG
- static const uint32 si_power_island_test_array[] = {
- 0x0000, 0x0001, 0x0010, 0x0011,
- 0x0100, 0x0101, 0x0110, 0x0111,
- 0x1000, 0x1001, 0x1010, 0x1011,
- 0x1100, 0x1101, 0x1110, 0x1111
- };
- #endif /* SR_DEBUG */
- int do_4360_pcie2_war = 0;
- #ifdef BCMULP
- /* Variable to store boot_type: warm_boot/cold_boot/etc. */
- static int boot_type = 0;
- #endif // endif
- /* global kernel resource */
- static si_info_t ksii;
- static si_cores_info_t ksii_cores_info;
- /**
- * Allocate an si handle. This function may be called multiple times.
- *
- * devid - pci device id (used to determine chip#)
- * osh - opaque OS handle
- * regs - virtual address of initial core registers
- * bustype - pci/pcmcia/sb/sdio/etc
- * vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
- * function set 'vars' to NULL, making dereferencing of this parameter undesired.
- * varsz - pointer to int to return the size of the vars
- */
- si_t *
- si_attach(uint devid, osl_t *osh, volatile void *regs,
- uint bustype, void *sdh, char **vars, uint *varsz)
- {
- si_info_t *sii;
- si_cores_info_t *cores_info;
- /* alloc si_info_t */
- /* freed after ucode download for firmware builds */
- if ((sii = MALLOCZ_NOPERSIST(osh, sizeof(si_info_t))) == NULL) {
- SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
- return (NULL);
- }
- /* alloc si_cores_info_t */
- if ((cores_info = (si_cores_info_t *)MALLOCZ(osh,
- sizeof(si_cores_info_t))) == NULL) {
- SI_ERROR(("si_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh)));
- MFREE(osh, sii, sizeof(si_info_t));
- return (NULL);
- }
- sii->cores_info = cores_info;
- if (si_doattach(sii, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) {
- MFREE(osh, sii, sizeof(si_info_t));
- MFREE(osh, cores_info, sizeof(si_cores_info_t));
- return (NULL);
- }
- sii->vars = vars ? *vars : NULL;
- sii->varsz = varsz ? *varsz : 0;
- return (si_t *)sii;
- }
- static uint32 wd_msticks; /**< watchdog timer ticks normalized to ms */
- /** Returns the backplane address of the chipcommon core for a particular chip */
- uint32
- si_enum_base(uint devid)
- {
- // NIC/DHD build
- switch (devid) {
- case BCM7271_CHIP_ID:
- case BCM7271_D11AC_ID:
- case BCM7271_D11AC2G_ID:
- case BCM7271_D11AC5G_ID:
- return 0xF1800000;
- }
- return SI_ENUM_BASE_DEFAULT;
- }
- /** generic kernel variant of si_attach(). Is not called for Linux WLAN NIC builds. */
- si_t *
- si_kattach(osl_t *osh)
- {
- static bool ksii_attached = FALSE;
- si_cores_info_t *cores_info;
- if (!ksii_attached) {
- void *regs = NULL;
- const uint device_id = BCM4710_DEVICE_ID; // pick an arbitrary default device_id
- regs = REG_MAP(si_enum_base(device_id), SI_CORE_SIZE); // map physical to virtual
- cores_info = (si_cores_info_t *)&ksii_cores_info;
- ksii.cores_info = cores_info;
- ASSERT(osh);
- if (si_doattach(&ksii, device_id, osh, regs,
- SI_BUS, NULL,
- osh != SI_OSH ? &(ksii.vars) : NULL,
- osh != SI_OSH ? &(ksii.varsz) : NULL) == NULL) {
- SI_ERROR(("si_kattach: si_doattach failed\n"));
- REG_UNMAP(regs);
- return NULL;
- }
- REG_UNMAP(regs);
- /* save ticks normalized to ms for si_watchdog_ms() */
- if (PMUCTL_ENAB(&ksii.pub)) {
- /* based on 32KHz ILP clock */
- wd_msticks = 32;
- } else {
- wd_msticks = ALP_CLOCK / 1000;
- }
- ksii_attached = TRUE;
- SI_MSG(("si_kattach done. ccrev = %d, wd_msticks = %d\n",
- CCREV(ksii.pub.ccrev), wd_msticks));
- }
- return &ksii.pub;
- }
- static bool
- si_buscore_prep(si_info_t *sii, uint bustype, uint devid, void *sdh)
- {
- BCM_REFERENCE(sdh);
- BCM_REFERENCE(devid);
- /* need to set memseg flag for CF card first before any sb registers access */
- if (BUSTYPE(bustype) == PCMCIA_BUS)
- sii->memseg = TRUE;
- #if defined(BCMSDIO) && !defined(BCMSDIOLITE)
- if (BUSTYPE(bustype) == SDIO_BUS) {
- int err;
- uint8 clkset;
- /* Try forcing SDIO core to do ALPAvail request only */
- clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
- bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
- if (!err) {
- uint8 clkval;
- /* If register supported, wait for ALPAvail and then force ALP */
- clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL);
- if ((clkval & ~SBSDIO_AVBITS) == clkset) {
- SPINWAIT(((clkval = bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
- SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)),
- PMU_MAX_TRANSITION_DLY);
- if (!SBSDIO_ALPAV(clkval)) {
- SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n",
- clkval));
- return FALSE;
- }
- clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
- bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
- clkset, &err);
- OSL_DELAY(65);
- }
- }
- /* Also, disable the extra SDIO pull-ups */
- bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
- }
- #ifdef BCMSPI
- /* Avoid backplane accesses before wake-wlan (i.e. htavail) for spi.
- * F1 read accesses may return correct data but with data-not-available dstatus bit set.
- */
- if (BUSTYPE(bustype) == SPI_BUS) {
- int err;
- uint32 regdata;
- /* wake up wlan function :WAKE_UP goes as HT_AVAIL request in hardware */
- regdata = bcmsdh_cfg_read_word(sdh, SDIO_FUNC_0, SPID_CONFIG, NULL);
- SI_MSG(("F0 REG0 rd = 0x%x\n", regdata));
- regdata |= WAKE_UP;
- bcmsdh_cfg_write_word(sdh, SDIO_FUNC_0, SPID_CONFIG, regdata, &err);
- OSL_DELAY(100000);
- }
- #endif /* BCMSPI */
- #endif /* BCMSDIO && BCMDONGLEHOST && !BCMSDIOLITE */
- return TRUE;
- }
- uint32
- si_get_pmu_reg_addr(si_t *sih, uint32 offset)
- {
- si_info_t *sii = SI_INFO(sih);
- uint32 pmuaddr = INVALID_ADDR;
- uint origidx = 0;
- SI_MSG(("%s: pmu access, offset: %x\n", __FUNCTION__, offset));
- if (!(sii->pub.cccaps & CC_CAP_PMU)) {
- goto done;
- }
- if (AOB_ENAB(&sii->pub)) {
- uint pmucoreidx;
- pmuregs_t *pmu;
- SI_MSG(("%s: AOBENAB: %x\n", __FUNCTION__, offset));
- origidx = sii->curidx;
- pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
- pmu = si_setcoreidx(&sii->pub, pmucoreidx);
- pmuaddr = (uint32)(uintptr)((volatile uint8*)pmu + offset);
- si_setcoreidx(sih, origidx);
- } else
- pmuaddr = SI_ENUM_BASE(sih) + offset;
- done:
- printf("%s: addrRET: %x\n", __FUNCTION__, pmuaddr);
- return pmuaddr;
- }
- static bool
- si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, uint32 savewin,
- uint *origidx, volatile void *regs)
- {
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- bool pci, pcie, pcie_gen2 = FALSE;
- uint i;
- uint pciidx, pcieidx, pcirev, pcierev;
- #if defined(BCM_BACKPLANE_TIMEOUT) || defined(AXI_TIMEOUTS)
- /* first, enable backplane timeouts */
- si_slave_wrapper_add(&sii->pub);
- #endif // endif
- sii->curidx = 0;
- cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
- ASSERT((uintptr)cc);
- /* get chipcommon rev */
- sii->pub.ccrev = (int)si_corerev(&sii->pub);
- /* get chipcommon chipstatus */
- if (CCREV(sii->pub.ccrev) >= 11)
- sii->pub.chipst = R_REG(sii->osh, &cc->chipstatus);
- /* get chipcommon capabilites */
- sii->pub.cccaps = R_REG(sii->osh, &cc->capabilities);
- /* get chipcommon extended capabilities */
- if (CCREV(sii->pub.ccrev) >= 35)
- sii->pub.cccaps_ext = R_REG(sii->osh, &cc->capabilities_ext);
- /* get pmu rev and caps */
- if (sii->pub.cccaps & CC_CAP_PMU) {
- if (AOB_ENAB(&sii->pub)) {
- uint pmucoreidx;
- pmuregs_t *pmu;
- struct si_pub *sih = &sii->pub;
- pmucoreidx = si_findcoreidx(&sii->pub, PMU_CORE_ID, 0);
- if (!GOODIDX(pmucoreidx)) {
- SI_ERROR(("si_buscore_setup: si_findcoreidx failed\n"));
- return FALSE;
- }
- pmu = si_setcoreidx(&sii->pub, pmucoreidx);
- sii->pub.pmucaps = R_REG(sii->osh, &pmu->pmucapabilities);
- si_setcoreidx(&sii->pub, SI_CC_IDX);
- sii->pub.gcirev = si_corereg(sih,
- GCI_CORE_IDX(sih),
- GCI_OFFSETOF(sih, gci_corecaps0), 0, 0) & GCI_CAP0_REV_MASK;
- } else
- sii->pub.pmucaps = R_REG(sii->osh, &cc->pmucapabilities);
- sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
- }
- SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
- CCREV(sii->pub.ccrev), sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
- sii->pub.pmucaps));
- /* figure out bus/orignal core idx */
- sii->pub.buscoretype = NODEV_CORE_ID;
- sii->pub.buscorerev = (uint)NOREV;
- sii->pub.buscoreidx = BADIDX;
- pci = pcie = FALSE;
- pcirev = pcierev = (uint)NOREV;
- pciidx = pcieidx = BADIDX;
- for (i = 0; i < sii->numcores; i++) {
- uint cid, crev;
- si_setcoreidx(&sii->pub, i);
- cid = si_coreid(&sii->pub);
- crev = si_corerev(&sii->pub);
- /* Display cores found */
- SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x size:%x regs 0x%p\n",
- i, cid, crev, sii->coresba[i], sii->coresba_size[i],
- OSL_OBFUSCATE_BUF(sii->regs[i])));
- if (BUSTYPE(bustype) == SI_BUS) {
- /* now look at the chipstatus register to figure the pacakge */
- /* for SDIO but downloaded on PCIE dev */
- #ifdef BCMPCIEDEV_ENABLED
- if (cid == PCIE2_CORE_ID) {
- pcieidx = i;
- pcierev = crev;
- pcie = TRUE;
- pcie_gen2 = TRUE;
- }
- #endif // endif
- } else if (BUSTYPE(bustype) == PCI_BUS) {
- if (cid == PCI_CORE_ID) {
- pciidx = i;
- pcirev = crev;
- pci = TRUE;
- } else if ((cid == PCIE_CORE_ID) || (cid == PCIE2_CORE_ID)) {
- pcieidx = i;
- pcierev = crev;
- pcie = TRUE;
- if (cid == PCIE2_CORE_ID)
- pcie_gen2 = TRUE;
- }
- } else if ((BUSTYPE(bustype) == PCMCIA_BUS) &&
- (cid == PCMCIA_CORE_ID)) {
- sii->pub.buscorerev = crev;
- sii->pub.buscoretype = cid;
- sii->pub.buscoreidx = i;
- }
- #ifdef BCMSDIO
- else if (((BUSTYPE(bustype) == SDIO_BUS) ||
- (BUSTYPE(bustype) == SPI_BUS)) &&
- ((cid == PCMCIA_CORE_ID) ||
- (cid == SDIOD_CORE_ID))) {
- sii->pub.buscorerev = crev;
- sii->pub.buscoretype = cid;
- sii->pub.buscoreidx = i;
- }
- #endif /* BCMSDIO */
- /* find the core idx before entering this func. */
- if ((savewin && (savewin == cores_info->coresba[i])) ||
- (regs == cores_info->regs[i]))
- *origidx = i;
- }
- #if defined(PCIE_FULL_DONGLE)
- if (pcie) {
- if (pcie_gen2)
- sii->pub.buscoretype = PCIE2_CORE_ID;
- else
- sii->pub.buscoretype = PCIE_CORE_ID;
- sii->pub.buscorerev = pcierev;
- sii->pub.buscoreidx = pcieidx;
- }
- BCM_REFERENCE(pci);
- BCM_REFERENCE(pcirev);
- BCM_REFERENCE(pciidx);
- #else
- if (pci) {
- sii->pub.buscoretype = PCI_CORE_ID;
- sii->pub.buscorerev = pcirev;
- sii->pub.buscoreidx = pciidx;
- } else if (pcie) {
- if (pcie_gen2)
- sii->pub.buscoretype = PCIE2_CORE_ID;
- else
- sii->pub.buscoretype = PCIE_CORE_ID;
- sii->pub.buscorerev = pcierev;
- sii->pub.buscoreidx = pcieidx;
- }
- #endif /* defined(PCIE_FULL_DONGLE) */
- SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx, sii->pub.buscoretype,
- sii->pub.buscorerev));
- #if defined(BCMSDIO)
- /* Make sure any on-chip ARM is off (in case strapping is wrong), or downloaded code was
- * already running.
- */
- if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) {
- if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) ||
- si_setcore(&sii->pub, ARMCM3_CORE_ID, 0))
- si_core_disable(&sii->pub, 0);
- }
- #endif /* BCMSDIO && BCMDONGLEHOST */
- /* return to the original core */
- si_setcoreidx(&sii->pub, *origidx);
- return TRUE;
- }
- uint16
- si_chipid(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- return (sii->chipnew) ? sii->chipnew : sih->chip;
- }
- /* CHIP_ID's being mapped here should not be used anywhere else in the code */
- static void
- si_chipid_fixup(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- ASSERT(sii->chipnew == 0);
- switch (sih->chip) {
- case BCM43567_CHIP_ID:
- sii->chipnew = sih->chip; /* save it */
- sii->pub.chip = BCM43570_CHIP_ID; /* chip class */
- break;
- case BCM43562_CHIP_ID:
- case BCM4358_CHIP_ID:
- case BCM43566_CHIP_ID:
- sii->chipnew = sih->chip; /* save it */
- sii->pub.chip = BCM43569_CHIP_ID; /* chip class */
- break;
- case BCM4356_CHIP_ID:
- case BCM4371_CHIP_ID:
- sii->chipnew = sih->chip; /* save it */
- sii->pub.chip = BCM4354_CHIP_ID; /* chip class */
- break;
- case BCM4357_CHIP_ID:
- case BCM4361_CHIP_ID:
- sii->chipnew = sih->chip; /* save it */
- sii->pub.chip = BCM4347_CHIP_ID; /* chip class */
- break;
- #ifdef CHIPS_CUSTOMER_HW6
- case BCM4377_CHIP_ID:
- sii->chipnew = sih->chip; /* save it */
- sii->pub.chip = BCM4369_CHIP_ID; /* chip class */
- break;
- #endif /* CHIPS_CUSTOMER_HW6 */
- default:
- break;
- }
- }
- #ifdef BCMULP
- static void
- si_check_boot_type(si_t *sih, osl_t *osh)
- {
- if (sih->pmurev >= 30) {
- boot_type = PMU_REG_NEW(sih, swscratch, 0, 0);
- } else {
- boot_type = CHIPC_REG(sih, flashdata, 0, 0);
- }
- SI_ERROR(("%s: boot_type: 0x%08x\n", __func__, boot_type));
- }
- #endif /* BCMULP */
- #ifdef BCM_BACKPLANE_TIMEOUT
- uint32
- si_clear_backplane_to_fast(void *sih, void *addr)
- {
- si_t *_sih = DISCARD_QUAL(sih, si_t);
- if (CHIPTYPE(_sih->socitype) == SOCI_AI) {
- return ai_clear_backplane_to_fast(_sih, addr);
- }
- return 0;
- }
- const si_axi_error_info_t *
- si_get_axi_errlog_info(si_t *sih)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_AI) {
- return (const si_axi_error_info_t *)sih->err_info;
- }
- return NULL;
- }
- void
- si_reset_axi_errlog_info(si_t *sih)
- {
- if (sih->err_info) {
- sih->err_info->count = 0;
- }
- }
- #endif /* BCM_BACKPLANE_TIMEOUT */
- /**
- * Allocate an si handle. This function may be called multiple times. This function is called by
- * both si_attach() and si_kattach().
- *
- * vars - pointer to a to-be created pointer area for "environment" variables. Some callers of this
- * function set 'vars' to NULL.
- */
- static si_info_t *
- si_doattach(si_info_t *sii, uint devid, osl_t *osh, volatile void *regs,
- uint bustype, void *sdh, char **vars, uint *varsz)
- {
- struct si_pub *sih = &sii->pub;
- uint32 w, savewin;
- chipcregs_t *cc;
- char *pvars = NULL;
- uint origidx;
- #ifdef NVSRCX
- char *sromvars;
- #endif // endif
- ASSERT(GOODREGS(regs));
- savewin = 0;
- sih->buscoreidx = BADIDX;
- sii->device_removed = FALSE;
- sii->curmap = regs;
- sii->sdh = sdh;
- sii->osh = osh;
- sii->second_bar0win = ~0x0;
- sih->enum_base = si_enum_base(devid);
- #if defined(BCM_BACKPLANE_TIMEOUT)
- sih->err_info = MALLOCZ(osh, sizeof(si_axi_error_info_t));
- if (sih->err_info == NULL) {
- SI_ERROR(("%s: %zu bytes MALLOC FAILED",
- __FUNCTION__, sizeof(si_axi_error_info_t)));
- }
- #endif /* BCM_BACKPLANE_TIMEOUT */
- #if defined(BCM_BACKPLANE_TIMEOUT)
- osl_set_bpt_cb(osh, (void *)si_clear_backplane_to_fast, (void *)sih);
- #endif // endif
- /* check to see if we are a si core mimic'ing a pci core */
- if ((bustype == PCI_BUS) &&
- (OSL_PCI_READ_CONFIG(sii->osh, PCI_SPROM_CONTROL, sizeof(uint32)) == 0xffffffff)) {
- SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI "
- "devid:0x%x\n", __FUNCTION__, devid));
- bustype = SI_BUS;
- }
- /* find Chipcommon address */
- if (bustype == PCI_BUS) {
- savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
- if (!GOODCOREADDR(savewin, SI_ENUM_BASE(sih)))
- savewin = SI_ENUM_BASE(sih);
- OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE(sih));
- if (!regs)
- return NULL;
- cc = (chipcregs_t *)regs;
- #ifdef BCMSDIO
- } else if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
- cc = (chipcregs_t *)sii->curmap;
- #endif // endif
- } else {
- cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE(sih), SI_CORE_SIZE);
- }
- sih->bustype = bustype;
- #ifdef BCMBUSTYPE
- if (bustype != BUSTYPE(bustype)) {
- SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
- bustype, BUSTYPE(bustype)));
- return NULL;
- }
- #endif // endif
- /* bus/core/clk setup for register access */
- if (!si_buscore_prep(sii, bustype, devid, sdh)) {
- SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype));
- return NULL;
- }
- /* ChipID recognition.
- * We assume we can read chipid at offset 0 from the regs arg.
- * If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
- * some way of recognizing them needs to be added here.
- */
- if (!cc) {
- SI_ERROR(("%s: chipcommon register space is null \n", __FUNCTION__));
- return NULL;
- }
- w = R_REG(osh, &cc->chipid);
- if ((w & 0xfffff) == 148277) w -= 65532;
- sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
- /* Might as wll fill in chip id rev & pkg */
- sih->chip = w & CID_ID_MASK;
- sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
- sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
- si_chipid_fixup(sih);
- if (CHIPID(sih->chip) == BCM43465_CHIP_ID) {
- sih->chip = BCM4366_CHIP_ID;
- } else if (CHIPID(sih->chip) == BCM43525_CHIP_ID) {
- sih->chip = BCM4365_CHIP_ID;
- }
- sih->issim = IS_SIM(sih->chippkg);
- #ifdef CHIPS_CUSTOMER_HW6
- if (MULTIBP_CAP(sih))
- {
- sih->_multibp_enable = TRUE;
- }
- #endif // endif
- /* scan for cores */
- if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) {
- SI_MSG(("Found chip type SB (0x%08x)\n", w));
- sb_scan(&sii->pub, regs, devid);
- } else if ((CHIPTYPE(sii->pub.socitype) == SOCI_AI) ||
- (CHIPTYPE(sii->pub.socitype) == SOCI_NAI) ||
- (CHIPTYPE(sii->pub.socitype) == SOCI_DVTBUS)) {
- if (CHIPTYPE(sii->pub.socitype) == SOCI_AI)
- SI_MSG(("Found chip type AI (0x%08x)\n", w));
- else if (CHIPTYPE(sii->pub.socitype) == SOCI_NAI)
- SI_MSG(("Found chip type NAI (0x%08x)\n", w));
- else
- SI_MSG(("Found chip type DVT (0x%08x)\n", w));
- /* pass chipc address instead of original core base */
- if (sii->osh) {
- sii->axi_wrapper = (axi_wrapper_t *)MALLOCZ(sii->osh,
- (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS));
- if (sii->axi_wrapper == NULL) {
- SI_ERROR(("%s: %zu bytes MALLOC Failed", __FUNCTION__,
- (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS)));
- }
- } else {
- sii->axi_wrapper = NULL;
- }
- ai_scan(&sii->pub, (void *)(uintptr)cc, devid);
- } else if (CHIPTYPE(sii->pub.socitype) == SOCI_UBUS) {
- SI_MSG(("Found chip type UBUS (0x%08x), chip id = 0x%4x\n", w, sih->chip));
- /* pass chipc address instead of original core base */
- ub_scan(&sii->pub, (void *)(uintptr)cc, devid);
- } else {
- SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
- return NULL;
- }
- /* no cores found, bail out */
- if (sii->numcores == 0) {
- SI_ERROR(("si_doattach: could not find any cores\n"));
- return NULL;
- }
- /* bus/core/clk setup */
- origidx = SI_CC_IDX;
- if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
- SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
- goto exit;
- }
- #ifdef BCMULP
- if (BCMULP_ENAB()) {
- si_check_boot_type(sih, osh);
- if (ulp_module_init(osh, sih) != BCME_OK) {
- ULP_ERR(("%s: err in ulp_module_init\n", __FUNCTION__));
- goto exit;
- }
- }
- #endif /* BCMULP */
- #if !defined(_CFEZ_) || defined(CFG_WL)
- /* assume current core is CC */
- if ((CCREV(sii->pub.ccrev) == 0x25) && ((CHIPID(sih->chip) == BCM43236_CHIP_ID ||
- CHIPID(sih->chip) == BCM43235_CHIP_ID ||
- CHIPID(sih->chip) == BCM43234_CHIP_ID ||
- CHIPID(sih->chip) == BCM43238_CHIP_ID) &&
- (CHIPREV(sii->pub.chiprev) <= 2))) {
- if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
- uint clkdiv;
- clkdiv = R_REG(osh, &cc->clkdiv);
- /* otp_clk_div is even number, 120/14 < 9mhz */
- clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
- W_REG(osh, &cc->clkdiv, clkdiv);
- SI_ERROR(("%s: set clkdiv to %x\n", __FUNCTION__, clkdiv));
- }
- OSL_DELAY(10);
- }
- /* Set the clkdiv2 divisor bits (2:0) to 0x4 if srom is present */
- if (bustype == SI_BUS) {
- uint32 clkdiv2, sromprsnt, capabilities, srom_supported;
- capabilities = R_REG(osh, &cc->capabilities);
- srom_supported = capabilities & SROM_SUPPORTED;
- if (srom_supported)
- {
- sromprsnt = R_REG(osh, &cc->sromcontrol);
- sromprsnt = sromprsnt & SROM_PRSNT_MASK;
- if (sromprsnt) {
- /* SROM clock come from backplane clock/div2. Must <= 1Mhz */
- clkdiv2 = (R_REG(osh, &cc->clkdiv2) & ~CLKD2_SROM);
- clkdiv2 |= CLKD2_SROMDIV_192;
- W_REG(osh, &cc->clkdiv2, clkdiv2);
- }
- }
- }
- if (bustype == PCI_BUS) {
- }
- #endif // endif
- #ifdef BCM_SDRBL
- /* 4360 rom bootloader in PCIE case, if the SDR is enabled, But preotection is
- * not turned on, then we want to hold arm in reset.
- * Bottomline: In sdrenable case, we allow arm to boot only when protection is
- * turned on.
- */
- if (CHIP_HOSTIF_PCIE(&(sii->pub))) {
- uint32 sflags = si_arm_sflags(&(sii->pub));
- /* If SDR is enabled but protection is not turned on
- * then we want to force arm to WFI.
- */
- if ((sflags & (SISF_SDRENABLE | SISF_TCMPROT)) == SISF_SDRENABLE) {
- disable_arm_irq();
- while (1) {
- hnd_cpu_wait(sih);
- }
- }
- }
- #endif /* BCM_SDRBL */
- pvars = NULL;
- BCM_REFERENCE(pvars);
- {
- sii->lhl_ps_mode = LHL_PS_MODE_0;
- }
- if (!si_onetimeinit) {
- if (CCREV(sii->pub.ccrev) >= 20) {
- uint32 gpiopullup = 0, gpiopulldown = 0;
- cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
- ASSERT(cc != NULL);
- W_REG(osh, &cc->gpiopullup, gpiopullup);
- W_REG(osh, &cc->gpiopulldown, gpiopulldown);
- si_setcoreidx(sih, origidx);
- }
- }
- /* clear any previous epidiag-induced target abort */
- ASSERT(!si_taclear(sih, FALSE));
- #if defined(BCMPMU_STATS) && !defined(BCMPMU_STATS_DISABLED)
- si_pmustatstimer_init(sih);
- #endif /* BCMPMU_STATS */
- #ifdef BOOTLOADER_CONSOLE_OUTPUT
- /* Enable console prints */
- si_muxenab(sii, 3);
- #endif // endif
- return (sii);
- exit:
- return NULL;
- }
- /** may be called with core in reset */
- void
- si_detach(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- uint idx;
- if (BUSTYPE(sih->bustype) == SI_BUS)
- for (idx = 0; idx < SI_MAXCORES; idx++)
- if (cores_info->regs[idx]) {
- REG_UNMAP(cores_info->regs[idx]);
- cores_info->regs[idx] = NULL;
- }
- #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
- if (cores_info != &ksii_cores_info)
- #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
- MFREE(sii->osh, cores_info, sizeof(si_cores_info_t));
- #if defined(BCM_BACKPLANE_TIMEOUT)
- if (sih->err_info) {
- MFREE(sii->osh, sih->err_info, sizeof(si_axi_error_info_t));
- sii->pub.err_info = NULL;
- }
- #endif /* BCM_BACKPLANE_TIMEOUT */
- if (sii->axi_wrapper) {
- MFREE(sii->osh, sii->axi_wrapper,
- (sizeof(axi_wrapper_t) * SI_MAX_AXI_WRAPPERS));
- sii->axi_wrapper = NULL;
- }
- #if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
- if (sii != &ksii)
- #endif /* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
- MFREE(sii->osh, sii, sizeof(si_info_t));
- }
- void *
- si_osh(si_t *sih)
- {
- si_info_t *sii;
- sii = SI_INFO(sih);
- return sii->osh;
- }
- void
- si_setosh(si_t *sih, osl_t *osh)
- {
- si_info_t *sii;
- sii = SI_INFO(sih);
- if (sii->osh != NULL) {
- SI_ERROR(("osh is already set....\n"));
- ASSERT(!sii->osh);
- }
- sii->osh = osh;
- }
- /** register driver interrupt disabling and restoring callback functions */
- void
- si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
- void *intrsenabled_fn, void *intr_arg)
- {
- si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- sii->intr_arg = intr_arg;
- sii->intrsoff_fn = (si_intrsoff_t)intrsoff_fn;
- sii->intrsrestore_fn = (si_intrsrestore_t)intrsrestore_fn;
- sii->intrsenabled_fn = (si_intrsenabled_t)intrsenabled_fn;
- /* save current core id. when this function called, the current core
- * must be the core which provides driver functions(il, et, wl, etc.)
- */
- sii->dev_coreid = cores_info->coreid[sii->curidx];
- }
- void
- si_deregister_intr_callback(si_t *sih)
- {
- si_info_t *sii;
- sii = SI_INFO(sih);
- sii->intrsoff_fn = NULL;
- sii->intrsrestore_fn = NULL;
- sii->intrsenabled_fn = NULL;
- }
- uint
- si_intflag(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_intflag(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return R_REG(sii->osh, ((uint32 *)(uintptr)
- (sii->oob_router + OOB_STATUSA)));
- else {
- ASSERT(0);
- return 0;
- }
- }
- uint
- si_flag(si_t *sih)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_flag(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_flag(sih);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_flag(sih);
- else {
- ASSERT(0);
- return 0;
- }
- }
- uint
- si_flag_alt(si_t *sih)
- {
- if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_flag_alt(sih);
- else {
- ASSERT(0);
- return 0;
- }
- }
- void
- si_setint(si_t *sih, int siflag)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- sb_setint(sih, siflag);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- ai_setint(sih, siflag);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- ub_setint(sih, siflag);
- else
- ASSERT(0);
- }
- uint32
- si_oobr_baseaddr(si_t *sih, bool second)
- {
- si_info_t *sii = SI_INFO(sih);
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return 0;
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return (second ? sii->oob_router1 : sii->oob_router);
- else {
- ASSERT(0);
- return 0;
- }
- }
- uint
- si_coreid(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- return cores_info->coreid[sii->curidx];
- }
- uint
- si_coreidx(si_t *sih)
- {
- si_info_t *sii;
- sii = SI_INFO(sih);
- return sii->curidx;
- }
- volatile void *
- si_d11_switch_addrbase(si_t *sih, uint coreunit)
- {
- return si_setcore(sih, D11_CORE_ID, coreunit);
- }
- /** return the core-type instantiation # of the current core */
- uint
- si_coreunit(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- uint idx;
- uint coreid;
- uint coreunit;
- uint i;
- coreunit = 0;
- idx = sii->curidx;
- ASSERT(GOODREGS(sii->curmap));
- coreid = si_coreid(sih);
- /* count the cores of our type */
- for (i = 0; i < idx; i++)
- if (cores_info->coreid[i] == coreid)
- coreunit++;
- return (coreunit);
- }
- uint
- si_corevendor(si_t *sih)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_corevendor(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_corevendor(sih);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_corevendor(sih);
- else {
- ASSERT(0);
- return 0;
- }
- }
- bool
- si_backplane64(si_t *sih)
- {
- return ((sih->cccaps & CC_CAP_BKPLN64) != 0);
- }
- uint
- si_corerev(si_t *sih)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_corerev(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_corerev(sih);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_corerev(sih);
- else {
- ASSERT(0);
- return 0;
- }
- }
- uint
- si_corerev_minor(si_t *sih)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_AI) {
- return ai_corerev_minor(sih);
- } else {
- return 0;
- }
- }
- /* return index of coreid or BADIDX if not found */
- uint
- si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
- {
- si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- uint found;
- uint i;
- found = 0;
- for (i = 0; i < sii->numcores; i++)
- if (cores_info->coreid[i] == coreid) {
- if (found == coreunit)
- return (i);
- found++;
- }
- return (BADIDX);
- }
- /** return total coreunit of coreid or zero if not found */
- uint
- si_numcoreunits(si_t *sih, uint coreid)
- {
- si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- uint found = 0;
- uint i;
- for (i = 0; i < sii->numcores; i++) {
- if (cores_info->coreid[i] == coreid) {
- found++;
- }
- }
- return found;
- }
- /** return total D11 coreunits */
- uint
- BCMRAMFN(si_numd11coreunits)(si_t *sih)
- {
- uint found = 0;
- found = si_numcoreunits(sih, D11_CORE_ID);
- #if defined(WLRSDB) && defined(WLRSDB_DISABLED)
- /* If RSDB functionality is compiled out,
- * then ignore any D11 cores beyond the first
- * Used in norsdb dongle build variants for rsdb chip.
- */
- found = 1;
- #endif /* defined(WLRSDB) && !defined(WLRSDB_DISABLED) */
- return found;
- }
- /** return list of found cores */
- uint
- si_corelist(si_t *sih, uint coreid[])
- {
- si_info_t *sii = SI_INFO(sih);
- si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
- bcopy((uchar*)cores_info->coreid, (uchar*)coreid, (sii->numcores * sizeof(uint)));
- return (sii->numcores);
- }
- /** return current wrapper mapping */
- void *
- si_wrapperregs(si_t *sih)
- {
- si_info_t *sii;
- sii = SI_INFO(sih);
- ASSERT(GOODREGS(sii->curwrap));
- return (sii->curwrap);
- }
- /** return current register mapping */
- volatile void *
- si_coreregs(si_t *sih)
- {
- si_info_t *sii;
- sii = SI_INFO(sih);
- ASSERT(GOODREGS(sii->curmap));
- return (sii->curmap);
- }
- /**
- * This function changes logical "focus" to the indicated core;
- * must be called with interrupts off.
- * Moreover, callers should keep interrupts off during switching out of and back to d11 core
- */
- volatile void *
- si_setcore(si_t *sih, uint coreid, uint coreunit)
- {
- uint idx;
- idx = si_findcoreidx(sih, coreid, coreunit);
- if (!GOODIDX(idx))
- return (NULL);
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_setcoreidx(sih, idx);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_setcoreidx(sih, idx);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_setcoreidx(sih, idx);
- else {
- ASSERT(0);
- return NULL;
- }
- }
- volatile void *
- si_setcoreidx(si_t *sih, uint coreidx)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_setcoreidx(sih, coreidx);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_setcoreidx(sih, coreidx);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_setcoreidx(sih, coreidx);
- else {
- ASSERT(0);
- return NULL;
- }
- }
- /** Turn off interrupt as required by sb_setcore, before switch core */
- volatile void *
- si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
- {
- volatile void *cc;
- si_info_t *sii = SI_INFO(sih);
- if (SI_FAST(sii)) {
- /* Overloading the origidx variable to remember the coreid,
- * this works because the core ids cannot be confused with
- * core indices.
- */
- *origidx = coreid;
- if (coreid == CC_CORE_ID)
- return (volatile void *)CCREGS_FAST(sii);
- else if (coreid == BUSCORETYPE(sih->buscoretype))
- return (volatile void *)PCIEREGS(sii);
- }
- INTR_OFF(sii, *intr_val);
- *origidx = sii->curidx;
- cc = si_setcore(sih, coreid, 0);
- ASSERT(cc != NULL);
- return cc;
- }
- /* restore coreidx and restore interrupt */
- void
- si_restore_core(si_t *sih, uint coreid, uint intr_val)
- {
- si_info_t *sii = SI_INFO(sih);
- if (SI_FAST(sii) && ((coreid == CC_CORE_ID) || (coreid == BUSCORETYPE(sih->buscoretype))))
- return;
- si_setcoreidx(sih, coreid);
- INTR_RESTORE(sii, intr_val);
- }
- int
- si_numaddrspaces(si_t *sih)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_numaddrspaces(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_numaddrspaces(sih);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_numaddrspaces(sih);
- else {
- ASSERT(0);
- return 0;
- }
- }
- /* Return the address of the nth address space in the current core
- * Arguments:
- * sih : Pointer to struct si_t
- * spidx : slave port index
- * baidx : base address index
- */
- uint32
- si_addrspace(si_t *sih, uint spidx, uint baidx)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_addrspace(sih, baidx);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_addrspace(sih, spidx, baidx);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_addrspace(sih, baidx);
- else {
- ASSERT(0);
- return 0;
- }
- }
- /* Return the size of the nth address space in the current core
- * Arguments:
- * sih : Pointer to struct si_t
- * spidx : slave port index
- * baidx : base address index
- */
- uint32
- si_addrspacesize(si_t *sih, uint spidx, uint baidx)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_addrspacesize(sih, baidx);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_addrspacesize(sih, spidx, baidx);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_addrspacesize(sih, baidx);
- else {
- ASSERT(0);
- return 0;
- }
- }
- void
- si_coreaddrspaceX(si_t *sih, uint asidx, uint32 *addr, uint32 *size)
- {
- /* Only supported for SOCI_AI */
- if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- ai_coreaddrspaceX(sih, asidx, addr, size);
- else
- *size = 0;
- }
- uint32
- si_core_cflags(si_t *sih, uint32 mask, uint32 val)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_core_cflags(sih, mask, val);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_core_cflags(sih, mask, val);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_core_cflags(sih, mask, val);
- else {
- ASSERT(0);
- return 0;
- }
- }
- void
- si_core_cflags_wo(si_t *sih, uint32 mask, uint32 val)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- sb_core_cflags_wo(sih, mask, val);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- ai_core_cflags_wo(sih, mask, val);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- ub_core_cflags_wo(sih, mask, val);
- else
- ASSERT(0);
- }
- uint32
- si_core_sflags(si_t *sih, uint32 mask, uint32 val)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_core_sflags(sih, mask, val);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_core_sflags(sih, mask, val);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_core_sflags(sih, mask, val);
- else {
- ASSERT(0);
- return 0;
- }
- }
- void
- si_commit(si_t *sih)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- sb_commit(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- ;
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- ;
- else {
- ASSERT(0);
- }
- }
- bool
- si_iscoreup(si_t *sih)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_iscoreup(sih);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_iscoreup(sih);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_iscoreup(sih);
- else {
- ASSERT(0);
- return FALSE;
- }
- }
- uint
- si_wrapperreg(si_t *sih, uint32 offset, uint32 mask, uint32 val)
- {
- /* only for AI back plane chips */
- if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return (ai_wrap_reg(sih, offset, mask, val));
- return 0;
- }
- /* si_backplane_access is used to read full backplane address from host for PCIE FD
- * it uses secondary bar-0 window which lies at an offset of 16K from primary bar-0
- * Provides support for read/write of 1/2/4 bytes of backplane address
- * Can be used to read/write
- * 1. core regs
- * 2. Wrapper regs
- * 3. memory
- * 4. BT area
- * For accessing any 32 bit backplane address, [31 : 12] of backplane should be given in "region"
- * [11 : 0] should be the "regoff"
- * for reading 4 bytes from reg 0x200 of d11 core use it like below
- * : si_backplane_access(sih, 0x18001000, 0x200, 4, 0, TRUE)
- */
- static int si_backplane_addr_sane(uint addr, uint size)
- {
- int bcmerror = BCME_OK;
- /* For 2 byte access, address has to be 2 byte aligned */
- if (size == 2) {
- if (addr & 0x1) {
- bcmerror = BCME_ERROR;
- }
- }
- /* For 4 byte access, address has to be 4 byte aligned */
- if (size == 4) {
- if (addr & 0x3) {
- bcmerror = BCME_ERROR;
- }
- }
- return bcmerror;
- }
- void
- si_invalidate_second_bar0win(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- sii->second_bar0win = ~0x0;
- }
- int
- si_backplane_access(si_t *sih, uint addr, uint size, uint *val, bool read)
- {
- volatile uint32 *r = NULL;
- uint32 region = 0;
- si_info_t *sii = SI_INFO(sih);
- /* Valid only for pcie bus */
- if (BUSTYPE(sih->bustype) != PCI_BUS) {
- SI_ERROR(("Valid only for pcie bus \n"));
- return BCME_ERROR;
- }
- /* Split adrr into region and address offset */
- region = (addr & (0xFFFFF << 12));
- addr = addr & 0xFFF;
- /* check for address and size sanity */
- if (si_backplane_addr_sane(addr, size) != BCME_OK)
- return BCME_ERROR;
- /* Update window if required */
- if (sii->second_bar0win != region) {
- OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_CORE2_WIN, 4, region);
- sii->second_bar0win = region;
- }
- /* Estimate effective address
- * sii->curmap : bar-0 virtual address
- * PCI_SECOND_BAR0_OFFSET : secondar bar-0 offset
- * regoff : actual reg offset
- */
- r = (volatile uint32 *)((volatile char *)sii->curmap + PCI_SECOND_BAR0_OFFSET + addr);
- SI_VMSG(("si curmap %p region %x regaddr %x effective addr %p READ %d\n",
- (volatile char*)sii->curmap, region, addr, r, read));
- switch (size) {
- case sizeof(uint8) :
- if (read)
- *val = R_REG(sii->osh, (volatile uint8*)r);
- else
- W_REG(sii->osh, (volatile uint8*)r, *val);
- break;
- case sizeof(uint16) :
- if (read)
- *val = R_REG(sii->osh, (volatile uint16*)r);
- else
- W_REG(sii->osh, (volatile uint16*)r, *val);
- break;
- case sizeof(uint32) :
- if (read)
- *val = R_REG(sii->osh, (volatile uint32*)r);
- else
- W_REG(sii->osh, (volatile uint32*)r, *val);
- break;
- default :
- SI_ERROR(("Invalid size %d \n", size));
- return (BCME_ERROR);
- break;
- }
- return (BCME_OK);
- }
- uint
- si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_corereg(sih, coreidx, regoff, mask, val);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_corereg(sih, coreidx, regoff, mask, val);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- return ub_corereg(sih, coreidx, regoff, mask, val);
- else {
- ASSERT(0);
- return 0;
- }
- }
- uint
- si_corereg_writeonly(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
- {
- return ai_corereg_writeonly(sih, coreidx, regoff, mask, val);
- }
- /** ILP sensitive register access needs special treatment to avoid backplane stalls */
- bool si_pmu_is_ilp_sensitive(uint32 idx, uint regoff)
- {
- if (idx == SI_CC_IDX) {
- if (CHIPCREGS_ILP_SENSITIVE(regoff))
- return TRUE;
- } else if (PMUREGS_ILP_SENSITIVE(regoff)) {
- return TRUE;
- }
- return FALSE;
- }
- /** 'idx' should refer either to the chipcommon core or the PMU core */
- uint
- si_pmu_corereg(si_t *sih, uint32 idx, uint regoff, uint mask, uint val)
- {
- int pmustatus_offset;
- /* prevent backplane stall on double write to 'ILP domain' registers in the PMU */
- if (mask != 0 && PMUREV(sih->pmurev) >= 22 &&
- si_pmu_is_ilp_sensitive(idx, regoff)) {
- pmustatus_offset = AOB_ENAB(sih) ? OFFSETOF(pmuregs_t, pmustatus) :
- OFFSETOF(chipcregs_t, pmustatus);
- while (si_corereg(sih, idx, pmustatus_offset, 0, 0) & PST_SLOW_WR_PENDING)
- {};
- }
- return si_corereg(sih, idx, regoff, mask, val);
- }
- /*
- * If there is no need for fiddling with interrupts or core switches (typically silicon
- * back plane registers, pci registers and chipcommon registers), this function
- * returns the register offset on this core to a mapped address. This address can
- * be used for W_REG/R_REG directly.
- *
- * For accessing registers that would need a core switch, this function will return
- * NULL.
- */
- volatile uint32 *
- si_corereg_addr(si_t *sih, uint coreidx, uint regoff)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- return sb_corereg_addr(sih, coreidx, regoff);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- return ai_corereg_addr(sih, coreidx, regoff);
- else {
- return 0;
- }
- }
- void
- si_core_disable(si_t *sih, uint32 bits)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- sb_core_disable(sih, bits);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- ai_core_disable(sih, bits);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- ub_core_disable(sih, bits);
- }
- void
- si_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
- {
- if (CHIPTYPE(sih->socitype) == SOCI_SB)
- sb_core_reset(sih, bits, resetbits);
- else if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI))
- ai_core_reset(sih, bits, resetbits);
- else if (CHIPTYPE(sih->socitype) == SOCI_UBUS)
- ub_core_reset(sih, bits, resetbits);
- }
- /** Run bist on current core. Caller needs to take care of core-specific bist hazards */
- int
- si_corebist(si_t *sih)
- {
- uint32 cflags;
- int result = 0;
- /* Read core control flags */
- cflags = si_core_cflags(sih, 0, 0);
- /* Set bist & fgc */
- si_core_cflags(sih, ~0, (SICF_BIST_EN | SICF_FGC));
- /* Wait for bist done */
- SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 100000);
- if (si_core_sflags(sih, 0, 0) & SISF_BIST_ERROR)
- result = BCME_ERROR;
- /* Reset core control flags */
- si_core_cflags(sih, 0xffff, cflags);
- return result;
- }
- uint
- si_num_slaveports(si_t *sih, uint coreid)
- {
- uint idx = si_findcoreidx(sih, coreid, 0);
- uint num = 0;
- if (idx != BADIDX) {
- if (CHIPTYPE(sih->socitype) == SOCI_AI) {
- num = ai_num_slaveports(sih, idx);
- }
- }
- return num;
- }
- uint32
- si_get_slaveport_addr(si_t *sih, uint spidx, uint baidx, uint core_id, uint coreunit)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx = sii->curidx;
- uint32 addr = 0x0;
- if (!((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI)))
- goto done;
- si_setcore(sih, core_id, coreunit);
- addr = ai_addrspace(sih, spidx, baidx);
- si_setcoreidx(sih, origidx);
- done:
- return addr;
- }
- uint32
- si_get_d11_slaveport_addr(si_t *sih, uint spidx, uint baidx, uint coreunit)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx = sii->curidx;
- uint32 addr = 0x0;
- if (!((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS) ||
- (CHIPTYPE(sih->socitype) == SOCI_NAI)))
- goto done;
- si_setcore(sih, D11_CORE_ID, coreunit);
- addr = ai_addrspace(sih, spidx, baidx);
- si_setcoreidx(sih, origidx);
- done:
- return addr;
- }
- static uint32
- factor6(uint32 x)
- {
- switch (x) {
- case CC_F6_2: return 2;
- case CC_F6_3: return 3;
- case CC_F6_4: return 4;
- case CC_F6_5: return 5;
- case CC_F6_6: return 6;
- case CC_F6_7: return 7;
- default: return 0;
- }
- }
- /*
- * Divide the clock by the divisor with protection for
- * a zero divisor.
- */
- static uint32
- divide_clock(uint32 clock, uint32 div)
- {
- return div ? clock / div : 0;
- }
- /** calculate the speed the SI would run at given a set of clockcontrol values */
- uint32
- si_clock_rate(uint32 pll_type, uint32 n, uint32 m)
- {
- uint32 n1, n2, clock, m1, m2, m3, mc;
- n1 = n & CN_N1_MASK;
- n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
- if (pll_type == PLL_TYPE6) {
- if (m & CC_T6_MMASK)
- return CC_T6_M1;
- else
- return CC_T6_M0;
- } else if ((pll_type == PLL_TYPE1) ||
- (pll_type == PLL_TYPE3) ||
- (pll_type == PLL_TYPE4) ||
- (pll_type == PLL_TYPE7)) {
- n1 = factor6(n1);
- n2 += CC_F5_BIAS;
- } else if (pll_type == PLL_TYPE2) {
- n1 += CC_T2_BIAS;
- n2 += CC_T2_BIAS;
- ASSERT((n1 >= 2) && (n1 <= 7));
- ASSERT((n2 >= 5) && (n2 <= 23));
- } else if (pll_type == PLL_TYPE5) {
- return (100000000);
- } else
- ASSERT(0);
- /* PLL types 3 and 7 use BASE2 (25Mhz) */
- if ((pll_type == PLL_TYPE3) ||
- (pll_type == PLL_TYPE7)) {
- clock = CC_CLOCK_BASE2 * n1 * n2;
- } else
- clock = CC_CLOCK_BASE1 * n1 * n2;
- if (clock == 0)
- return 0;
- m1 = m & CC_M1_MASK;
- m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT;
- m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
- mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
- if ((pll_type == PLL_TYPE1) ||
- (pll_type == PLL_TYPE3) ||
- (pll_type == PLL_TYPE4) ||
- (pll_type == PLL_TYPE7)) {
- m1 = factor6(m1);
- if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
- m2 += CC_F5_BIAS;
- else
- m2 = factor6(m2);
- m3 = factor6(m3);
- switch (mc) {
- case CC_MC_BYPASS: return (clock);
- case CC_MC_M1: return divide_clock(clock, m1);
- case CC_MC_M1M2: return divide_clock(clock, m1 * m2);
- case CC_MC_M1M2M3: return divide_clock(clock, m1 * m2 * m3);
- case CC_MC_M1M3: return divide_clock(clock, m1 * m3);
- default: return (0);
- }
- } else {
- ASSERT(pll_type == PLL_TYPE2);
- m1 += CC_T2_BIAS;
- m2 += CC_T2M2_BIAS;
- m3 += CC_T2_BIAS;
- ASSERT((m1 >= 2) && (m1 <= 7));
- ASSERT((m2 >= 3) && (m2 <= 10));
- ASSERT((m3 >= 2) && (m3 <= 7));
- if ((mc & CC_T2MC_M1BYP) == 0)
- clock /= m1;
- if ((mc & CC_T2MC_M2BYP) == 0)
- clock /= m2;
- if ((mc & CC_T2MC_M3BYP) == 0)
- clock /= m3;
- return (clock);
- }
- }
- /**
- * Some chips could have multiple host interfaces, however only one will be active.
- * For a given chip. Depending pkgopt and cc_chipst return the active host interface.
- */
- uint
- si_chip_hostif(si_t *sih)
- {
- uint hosti = 0;
- switch (CHIPID(sih->chip)) {
- case BCM43018_CHIP_ID:
- case BCM43430_CHIP_ID:
- hosti = CHIP_HOSTIF_SDIOMODE;
- break;
- case BCM43012_CHIP_ID:
- hosti = CHIP_HOSTIF_SDIOMODE;
- break;
- CASE_BCM43602_CHIP:
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- case BCM4360_CHIP_ID:
- /* chippkg bit-0 == 0 is PCIE only pkgs
- * chippkg bit-0 == 1 has both PCIE and USB cores enabled
- */
- if ((sih->chippkg & 0x1) && (sih->chipst & CST4360_MODE_USB))
- hosti = CHIP_HOSTIF_USBMODE;
- else
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- case BCM4335_CHIP_ID:
- /* TBD: like in 4360, do we need to check pkg? */
- if (CST4335_CHIPMODE_USB20D(sih->chipst))
- hosti = CHIP_HOSTIF_USBMODE;
- else if (CST4335_CHIPMODE_SDIOD(sih->chipst))
- hosti = CHIP_HOSTIF_SDIOMODE;
- else
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- CASE_BCM4345_CHIP:
- if (CST4345_CHIPMODE_USB20D(sih->chipst) || CST4345_CHIPMODE_HSIC(sih->chipst))
- hosti = CHIP_HOSTIF_USBMODE;
- else if (CST4345_CHIPMODE_SDIOD(sih->chipst))
- hosti = CHIP_HOSTIF_SDIOMODE;
- else if (CST4345_CHIPMODE_PCIE(sih->chipst))
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- case BCM4349_CHIP_GRPID:
- case BCM53573_CHIP_GRPID:
- if (CST4349_CHIPMODE_SDIOD(sih->chipst))
- hosti = CHIP_HOSTIF_SDIOMODE;
- else if (CST4349_CHIPMODE_PCIE(sih->chipst))
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- case BCM4364_CHIP_ID:
- if (CST4364_CHIPMODE_SDIOD(sih->chipst))
- hosti = CHIP_HOSTIF_SDIOMODE;
- else if (CST4364_CHIPMODE_PCIE(sih->chipst))
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- case BCM4373_CHIP_ID:
- if (CST4373_CHIPMODE_USB20D(sih->chipst))
- hosti = CHIP_HOSTIF_USBMODE;
- else if (CST4373_CHIPMODE_SDIOD(sih->chipst))
- hosti = CHIP_HOSTIF_SDIOMODE;
- else if (CST4373_CHIPMODE_PCIE(sih->chipst))
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- case BCM4347_CHIP_GRPID:
- if (CST4347_CHIPMODE_SDIOD(sih->chipst))
- hosti = CHIP_HOSTIF_SDIOMODE;
- else if (CST4347_CHIPMODE_PCIE(sih->chipst))
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- case BCM4369_CHIP_GRPID:
- if (CST4369_CHIPMODE_SDIOD(sih->chipst))
- hosti = CHIP_HOSTIF_SDIOMODE;
- else if (CST4369_CHIPMODE_PCIE(sih->chipst))
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- #ifdef CHIPS_CUSTOMER_HW6
- case BCM4368_CHIP_GRPID:
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- #endif /* CHIPS_CUSTOMER_HW6 */
- case BCM4350_CHIP_ID:
- case BCM4354_CHIP_ID:
- case BCM43556_CHIP_ID:
- case BCM43558_CHIP_ID:
- case BCM43566_CHIP_ID:
- case BCM43568_CHIP_ID:
- case BCM43569_CHIP_ID:
- case BCM43570_CHIP_ID:
- case BCM4358_CHIP_ID:
- if (CST4350_CHIPMODE_USB20D(sih->chipst) ||
- CST4350_CHIPMODE_HSIC20D(sih->chipst) ||
- CST4350_CHIPMODE_USB30D(sih->chipst) ||
- CST4350_CHIPMODE_USB30D_WL(sih->chipst) ||
- CST4350_CHIPMODE_HSIC30D(sih->chipst))
- hosti = CHIP_HOSTIF_USBMODE;
- else if (CST4350_CHIPMODE_SDIOD(sih->chipst))
- hosti = CHIP_HOSTIF_SDIOMODE;
- else if (CST4350_CHIPMODE_PCIE(sih->chipst))
- hosti = CHIP_HOSTIF_PCIEMODE;
- break;
- default:
- break;
- }
- return hosti;
- }
- /** set chip watchdog reset timer to fire in 'ticks' */
- void
- si_watchdog(si_t *sih, uint ticks)
- {
- uint nb, maxt;
- uint pmu_wdt = 1;
- if (PMUCTL_ENAB(sih) && pmu_wdt) {
- nb = (CCREV(sih->ccrev) < 26) ? 16 : ((CCREV(sih->ccrev) >= 37) ? 32 : 24);
- /* The mips compiler uses the sllv instruction,
- * so we specially handle the 32-bit case.
- */
- if (nb == 32)
- maxt = 0xffffffff;
- else
- maxt = ((1 << nb) - 1);
- if (ticks == 1)
- ticks = 2;
- else if (ticks > maxt)
- ticks = maxt;
- if (CHIPID(sih->chip) == BCM43012_CHIP_ID) {
- PMU_REG_NEW(sih, min_res_mask, ~0, DEFAULT_43012_MIN_RES_MASK);
- PMU_REG_NEW(sih, watchdog_res_mask, ~0, DEFAULT_43012_MIN_RES_MASK);
- PMU_REG_NEW(sih, pmustatus, PST_WDRESET, PST_WDRESET);
- PMU_REG_NEW(sih, pmucontrol_ext, PCTL_EXT_FASTLPO_SWENAB, 0);
- SPINWAIT((PMU_REG(sih, pmustatus, 0, 0) & PST_ILPFASTLPO),
- PMU_MAX_TRANSITION_DLY);
- }
- pmu_corereg(sih, SI_CC_IDX, pmuwatchdog, ~0, ticks);
- } else {
- maxt = (1 << 28) - 1;
- if (ticks > maxt)
- ticks = maxt;
- si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
- }
- }
- /** trigger watchdog reset after ms milliseconds */
- void
- si_watchdog_ms(si_t *sih, uint32 ms)
- {
- si_watchdog(sih, wd_msticks * ms);
- }
- uint32 si_watchdog_msticks(void)
- {
- return wd_msticks;
- }
- bool
- si_taclear(si_t *sih, bool details)
- {
- return FALSE;
- }
- /** return the slow clock source - LPO, XTAL, or PCI */
- static uint
- si_slowclk_src(si_info_t *sii)
- {
- chipcregs_t *cc;
- ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
- if (CCREV(sii->pub.ccrev) < 6) {
- if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) &&
- (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(uint32)) &
- PCI_CFG_GPIO_SCS))
- return (SCC_SS_PCI);
- else
- return (SCC_SS_XTAL);
- } else if (CCREV(sii->pub.ccrev) < 10) {
- cc = (chipcregs_t *)si_setcoreidx(&sii->pub, sii->curidx);
- ASSERT(cc);
- return (R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK);
- } else /* Insta-clock */
- return (SCC_SS_XTAL);
- }
- /** return the ILP (slowclock) min or max frequency */
- static uint
- si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
- {
- uint32 slowclk;
- uint div;
- ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
- /* shouldn't be here unless we've established the chip has dynamic clk control */
- ASSERT(R_REG(sii->osh, &cc->capabilities) & CC_CAP_PWR_CTL);
- slowclk = si_slowclk_src(sii);
- if (CCREV(sii->pub.ccrev) < 6) {
- if (slowclk == SCC_SS_PCI)
- return (max_freq ? (PCIMAXFREQ / 64) : (PCIMINFREQ / 64));
- else
- return (max_freq ? (XTALMAXFREQ / 32) : (XTALMINFREQ / 32));
- } else if (CCREV(sii->pub.ccrev) < 10) {
- div = 4 *
- (((R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
- if (slowclk == SCC_SS_LPO)
- return (max_freq ? LPOMAXFREQ : LPOMINFREQ);
- else if (slowclk == SCC_SS_XTAL)
- return (max_freq ? (XTALMAXFREQ / div) : (XTALMINFREQ / div));
- else if (slowclk == SCC_SS_PCI)
- return (max_freq ? (PCIMAXFREQ / div) : (PCIMINFREQ / div));
- else
- ASSERT(0);
- } else {
- /* Chipc rev 10 is InstaClock */
- div = R_REG(sii->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT;
- div = 4 * (div + 1);
- return (max_freq ? XTALMAXFREQ : (XTALMINFREQ / div));
- }
- return (0);
- }
- static void
- si_clkctl_setdelay(si_info_t *sii, void *chipcregs)
- {
- chipcregs_t *cc = (chipcregs_t *)chipcregs;
- uint slowmaxfreq, pll_delay, slowclk;
- uint pll_on_delay, fref_sel_delay;
- pll_delay = PLL_DELAY;
- /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
- * since the xtal will also be powered down by dynamic clk control logic.
- */
- slowclk = si_slowclk_src(sii);
- if (slowclk != SCC_SS_XTAL)
- pll_delay += XTAL_ON_DELAY;
- /* Starting with 4318 it is ILP that is used for the delays */
- slowmaxfreq = si_slowclk_freq(sii, (CCREV(sii->pub.ccrev) >= 10) ? FALSE : TRUE, cc);
- pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
- fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
- W_REG(sii->osh, &cc->pll_on_delay, pll_on_delay);
- W_REG(sii->osh, &cc->fref_sel_delay, fref_sel_delay);
- }
- /** initialize power control delay registers */
- void
- si_clkctl_init(si_t *sih)
- {
- si_info_t *sii;
- uint origidx = 0;
- chipcregs_t *cc;
- bool fast;
- if (!CCCTL_ENAB(sih))
- return;
- sii = SI_INFO(sih);
- fast = SI_FAST(sii);
- if (!fast) {
- origidx = sii->curidx;
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL)
- return;
- } else if ((cc = (chipcregs_t *)CCREGS_FAST(sii)) == NULL)
- return;
- ASSERT(cc != NULL);
- /* set all Instaclk chip ILP to 1 MHz */
- if (CCREV(sih->ccrev) >= 10)
- SET_REG(sii->osh, &cc->system_clk_ctl, SYCC_CD_MASK,
- (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
- si_clkctl_setdelay(sii, (void *)(uintptr)cc);
- OSL_DELAY(20000);
- if (!fast)
- si_setcoreidx(sih, origidx);
- }
- /** change logical "focus" to the gpio core for optimized access */
- volatile void *
- si_gpiosetcore(si_t *sih)
- {
- return (si_setcoreidx(sih, SI_CC_IDX));
- }
- /**
- * mask & set gpiocontrol bits.
- * If a gpiocontrol bit is set to 0, chipcommon controls the corresponding GPIO pin.
- * If a gpiocontrol bit is set to 1, the GPIO pin is no longer a GPIO and becomes dedicated
- * to some chip-specific purpose.
- */
- uint32
- si_gpiocontrol(si_t *sih, uint32 mask, uint32 val, uint8 priority)
- {
- uint regoff;
- regoff = 0;
- /* gpios could be shared on router platforms
- * ignore reservation if it's high priority (e.g., test apps)
- */
- if ((priority != GPIO_HI_PRIORITY) &&
- (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
- mask = priority ? (si_gpioreservation & mask) :
- ((si_gpioreservation | mask) & ~(si_gpioreservation));
- val &= mask;
- }
- regoff = OFFSETOF(chipcregs_t, gpiocontrol);
- return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
- }
- /** mask&set gpio output enable bits */
- uint32
- si_gpioouten(si_t *sih, uint32 mask, uint32 val, uint8 priority)
- {
- uint regoff;
- regoff = 0;
- /* gpios could be shared on router platforms
- * ignore reservation if it's high priority (e.g., test apps)
- */
- if ((priority != GPIO_HI_PRIORITY) &&
- (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
- mask = priority ? (si_gpioreservation & mask) :
- ((si_gpioreservation | mask) & ~(si_gpioreservation));
- val &= mask;
- }
- regoff = OFFSETOF(chipcregs_t, gpioouten);
- return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
- }
- /** mask&set gpio output bits */
- uint32
- si_gpioout(si_t *sih, uint32 mask, uint32 val, uint8 priority)
- {
- uint regoff;
- regoff = 0;
- /* gpios could be shared on router platforms
- * ignore reservation if it's high priority (e.g., test apps)
- */
- if ((priority != GPIO_HI_PRIORITY) &&
- (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
- mask = priority ? (si_gpioreservation & mask) :
- ((si_gpioreservation | mask) & ~(si_gpioreservation));
- val &= mask;
- }
- regoff = OFFSETOF(chipcregs_t, gpioout);
- return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
- }
- /** reserve one gpio */
- uint32
- si_gpioreserve(si_t *sih, uint32 gpio_bitmask, uint8 priority)
- {
- /* only cores on SI_BUS share GPIO's and only applcation users need to
- * reserve/release GPIO
- */
- if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
- ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
- return 0xffffffff;
- }
- /* make sure only one bit is set */
- if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
- ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
- return 0xffffffff;
- }
- /* already reserved */
- if (si_gpioreservation & gpio_bitmask)
- return 0xffffffff;
- /* set reservation */
- si_gpioreservation |= gpio_bitmask;
- return si_gpioreservation;
- }
- /**
- * release one gpio.
- *
- * releasing the gpio doesn't change the current value on the GPIO last write value
- * persists till someone overwrites it.
- */
- uint32
- si_gpiorelease(si_t *sih, uint32 gpio_bitmask, uint8 priority)
- {
- /* only cores on SI_BUS share GPIO's and only applcation users need to
- * reserve/release GPIO
- */
- if ((BUSTYPE(sih->bustype) != SI_BUS) || (!priority)) {
- ASSERT((BUSTYPE(sih->bustype) == SI_BUS) && (priority));
- return 0xffffffff;
- }
- /* make sure only one bit is set */
- if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
- ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
- return 0xffffffff;
- }
- /* already released */
- if (!(si_gpioreservation & gpio_bitmask))
- return 0xffffffff;
- /* clear reservation */
- si_gpioreservation &= ~gpio_bitmask;
- return si_gpioreservation;
- }
- /* return the current gpioin register value */
- uint32
- si_gpioin(si_t *sih)
- {
- uint regoff;
- regoff = OFFSETOF(chipcregs_t, gpioin);
- return (si_corereg(sih, SI_CC_IDX, regoff, 0, 0));
- }
- /* mask&set gpio interrupt polarity bits */
- uint32
- si_gpiointpolarity(si_t *sih, uint32 mask, uint32 val, uint8 priority)
- {
- uint regoff;
- /* gpios could be shared on router platforms */
- if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
- mask = priority ? (si_gpioreservation & mask) :
- ((si_gpioreservation | mask) & ~(si_gpioreservation));
- val &= mask;
- }
- regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
- return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
- }
- /* mask&set gpio interrupt mask bits */
- uint32
- si_gpiointmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
- {
- uint regoff;
- /* gpios could be shared on router platforms */
- if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
- mask = priority ? (si_gpioreservation & mask) :
- ((si_gpioreservation | mask) & ~(si_gpioreservation));
- val &= mask;
- }
- regoff = OFFSETOF(chipcregs_t, gpiointmask);
- return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
- }
- uint32
- si_gpioeventintmask(si_t *sih, uint32 mask, uint32 val, uint8 priority)
- {
- uint regoff;
- /* gpios could be shared on router platforms */
- if ((BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) {
- mask = priority ? (si_gpioreservation & mask) :
- ((si_gpioreservation | mask) & ~(si_gpioreservation));
- val &= mask;
- }
- regoff = OFFSETOF(chipcregs_t, gpioeventintmask);
- return (si_corereg(sih, SI_CC_IDX, regoff, mask, val));
- }
- /* assign the gpio to an led */
- uint32
- si_gpioled(si_t *sih, uint32 mask, uint32 val)
- {
- if (CCREV(sih->ccrev) < 16)
- return 0xffffffff;
- /* gpio led powersave reg */
- return (si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val));
- }
- /* mask&set gpio timer val */
- uint32
- si_gpiotimerval(si_t *sih, uint32 mask, uint32 gpiotimerval)
- {
- if (CCREV(sih->ccrev) < 16)
- return 0xffffffff;
- return (si_corereg(sih, SI_CC_IDX,
- OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval));
- }
- uint32
- si_gpiopull(si_t *sih, bool updown, uint32 mask, uint32 val)
- {
- uint offs;
- if (CCREV(sih->ccrev) < 20)
- return 0xffffffff;
- offs = (updown ? OFFSETOF(chipcregs_t, gpiopulldown) : OFFSETOF(chipcregs_t, gpiopullup));
- return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
- }
- uint32
- si_gpioevent(si_t *sih, uint regtype, uint32 mask, uint32 val)
- {
- uint offs;
- if (CCREV(sih->ccrev) < 11)
- return 0xffffffff;
- if (regtype == GPIO_REGEVT)
- offs = OFFSETOF(chipcregs_t, gpioevent);
- else if (regtype == GPIO_REGEVT_INTMSK)
- offs = OFFSETOF(chipcregs_t, gpioeventintmask);
- else if (regtype == GPIO_REGEVT_INTPOL)
- offs = OFFSETOF(chipcregs_t, gpioeventintpolarity);
- else
- return 0xffffffff;
- return (si_corereg(sih, SI_CC_IDX, offs, mask, val));
- }
- uint32
- si_gpio_int_enable(si_t *sih, bool enable)
- {
- uint offs;
- if (CCREV(sih->ccrev) < 11)
- return 0xffffffff;
- offs = OFFSETOF(chipcregs_t, intmask);
- return (si_corereg(sih, SI_CC_IDX, offs, CI_GPIO, (enable ? CI_GPIO : 0)));
- }
- /** Return the size of the specified SYSMEM bank */
- static uint
- sysmem_banksize(si_info_t *sii, sysmemregs_t *regs, uint8 idx)
- {
- uint banksize, bankinfo;
- uint bankidx = idx;
- W_REG(sii->osh, ®s->bankidx, bankidx);
- bankinfo = R_REG(sii->osh, ®s->bankinfo);
- banksize = SYSMEM_BANKINFO_SZBASE * ((bankinfo & SYSMEM_BANKINFO_SZMASK) + 1);
- return banksize;
- }
- /** Return the RAM size of the SYSMEM core */
- uint32
- si_sysmem_size(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- sysmemregs_t *regs;
- bool wasup;
- uint32 coreinfo;
- uint memsize = 0;
- uint8 i;
- uint nb, nrb;
- /* Block ints and save current core */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- /* Switch to SYSMEM core */
- if (!(regs = si_setcore(sih, SYSMEM_CORE_ID, 0)))
- goto done;
- /* Get info for determining size */
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, 0, 0);
- coreinfo = R_REG(sii->osh, ®s->coreinfo);
- /* Number of ROM banks, SW need to skip the ROM banks. */
- nrb = (coreinfo & SYSMEM_SRCI_ROMNB_MASK) >> SYSMEM_SRCI_ROMNB_SHIFT;
- nb = (coreinfo & SYSMEM_SRCI_SRNB_MASK) >> SYSMEM_SRCI_SRNB_SHIFT;
- for (i = 0; i < nb; i++)
- memsize += sysmem_banksize(sii, regs, i + nrb);
- si_setcoreidx(sih, origidx);
- done:
- INTR_RESTORE(sii, intr_val);
- return memsize;
- }
- /** Return the size of the specified SOCRAM bank */
- static uint
- socram_banksize(si_info_t *sii, sbsocramregs_t *regs, uint8 idx, uint8 mem_type)
- {
- uint banksize, bankinfo;
- uint bankidx = idx | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
- ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
- W_REG(sii->osh, ®s->bankidx, bankidx);
- bankinfo = R_REG(sii->osh, ®s->bankinfo);
- banksize = SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
- return banksize;
- }
- void si_socram_set_bankpda(si_t *sih, uint32 bankidx, uint32 bankpda)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- sbsocramregs_t *regs;
- bool wasup;
- uint corerev;
- /* Block ints and save current core */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- /* Switch to SOCRAM core */
- if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
- goto done;
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, 0, 0);
- corerev = si_corerev(sih);
- if (corerev >= 16) {
- W_REG(sii->osh, ®s->bankidx, bankidx);
- W_REG(sii->osh, ®s->bankpda, bankpda);
- }
- /* Return to previous state and core */
- if (!wasup)
- si_core_disable(sih, 0);
- si_setcoreidx(sih, origidx);
- done:
- INTR_RESTORE(sii, intr_val);
- }
- void
- si_socdevram(si_t *sih, bool set, uint8 *enable, uint8 *protect, uint8 *remap)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- sbsocramregs_t *regs;
- bool wasup;
- uint corerev;
- /* Block ints and save current core */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- if (!set)
- *enable = *protect = *remap = 0;
- /* Switch to SOCRAM core */
- if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
- goto done;
- /* Get info for determining size */
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, 0, 0);
- corerev = si_corerev(sih);
- if (corerev >= 10) {
- uint32 extcinfo;
- uint8 nb;
- uint8 i;
- uint32 bankidx, bankinfo;
- extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
- nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
- for (i = 0; i < nb; i++) {
- bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
- W_REG(sii->osh, ®s->bankidx, bankidx);
- bankinfo = R_REG(sii->osh, ®s->bankinfo);
- if (set) {
- bankinfo &= ~SOCRAM_BANKINFO_DEVRAMSEL_MASK;
- bankinfo &= ~SOCRAM_BANKINFO_DEVRAMPRO_MASK;
- bankinfo &= ~SOCRAM_BANKINFO_DEVRAMREMAP_MASK;
- if (*enable) {
- bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMSEL_SHIFT);
- if (*protect)
- bankinfo |= (1 << SOCRAM_BANKINFO_DEVRAMPRO_SHIFT);
- if ((corerev >= 16) && *remap)
- bankinfo |=
- (1 << SOCRAM_BANKINFO_DEVRAMREMAP_SHIFT);
- }
- W_REG(sii->osh, ®s->bankinfo, bankinfo);
- } else if (i == 0) {
- if (bankinfo & SOCRAM_BANKINFO_DEVRAMSEL_MASK) {
- *enable = 1;
- if (bankinfo & SOCRAM_BANKINFO_DEVRAMPRO_MASK)
- *protect = 1;
- if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK)
- *remap = 1;
- }
- }
- }
- }
- /* Return to previous state and core */
- if (!wasup)
- si_core_disable(sih, 0);
- si_setcoreidx(sih, origidx);
- done:
- INTR_RESTORE(sii, intr_val);
- }
- bool
- si_socdevram_remap_isenb(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- sbsocramregs_t *regs;
- bool wasup, remap = FALSE;
- uint corerev;
- uint32 extcinfo;
- uint8 nb;
- uint8 i;
- uint32 bankidx, bankinfo;
- /* Block ints and save current core */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- /* Switch to SOCRAM core */
- if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
- goto done;
- /* Get info for determining size */
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, 0, 0);
- corerev = si_corerev(sih);
- if (corerev >= 16) {
- extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
- nb = ((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT);
- for (i = 0; i < nb; i++) {
- bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
- W_REG(sii->osh, ®s->bankidx, bankidx);
- bankinfo = R_REG(sii->osh, ®s->bankinfo);
- if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) {
- remap = TRUE;
- break;
- }
- }
- }
- /* Return to previous state and core */
- if (!wasup)
- si_core_disable(sih, 0);
- si_setcoreidx(sih, origidx);
- done:
- INTR_RESTORE(sii, intr_val);
- return remap;
- }
- bool
- si_socdevram_pkg(si_t *sih)
- {
- if (si_socdevram_size(sih) > 0)
- return TRUE;
- else
- return FALSE;
- }
- uint32
- si_socdevram_size(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- uint32 memsize = 0;
- sbsocramregs_t *regs;
- bool wasup;
- uint corerev;
- /* Block ints and save current core */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- /* Switch to SOCRAM core */
- if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
- goto done;
- /* Get info for determining size */
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, 0, 0);
- corerev = si_corerev(sih);
- if (corerev >= 10) {
- uint32 extcinfo;
- uint8 nb;
- uint8 i;
- extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
- nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
- for (i = 0; i < nb; i++)
- memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
- }
- /* Return to previous state and core */
- if (!wasup)
- si_core_disable(sih, 0);
- si_setcoreidx(sih, origidx);
- done:
- INTR_RESTORE(sii, intr_val);
- return memsize;
- }
- uint32
- si_socdevram_remap_size(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- uint32 memsize = 0, banksz;
- sbsocramregs_t *regs;
- bool wasup;
- uint corerev;
- uint32 extcinfo;
- uint8 nb;
- uint8 i;
- uint32 bankidx, bankinfo;
- /* Block ints and save current core */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- /* Switch to SOCRAM core */
- if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
- goto done;
- /* Get info for determining size */
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, 0, 0);
- corerev = si_corerev(sih);
- if (corerev >= 16) {
- extcinfo = R_REG(sii->osh, ®s->extracoreinfo);
- nb = (((extcinfo & SOCRAM_DEVRAMBANK_MASK) >> SOCRAM_DEVRAMBANK_SHIFT));
- /*
- * FIX: A0 Issue: Max addressable is 512KB, instead 640KB
- * Only four banks are accessible to ARM
- */
- if ((corerev == 16) && (nb == 5))
- nb = 4;
- for (i = 0; i < nb; i++) {
- bankidx = i | (SOCRAM_MEMTYPE_DEVRAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
- W_REG(sii->osh, ®s->bankidx, bankidx);
- bankinfo = R_REG(sii->osh, ®s->bankinfo);
- if (bankinfo & SOCRAM_BANKINFO_DEVRAMREMAP_MASK) {
- banksz = socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_DEVRAM);
- memsize += banksz;
- } else {
- /* Account only consecutive banks for now */
- break;
- }
- }
- }
- /* Return to previous state and core */
- if (!wasup)
- si_core_disable(sih, 0);
- si_setcoreidx(sih, origidx);
- done:
- INTR_RESTORE(sii, intr_val);
- return memsize;
- }
- /** Return the RAM size of the SOCRAM core */
- uint32
- si_socram_size(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- sbsocramregs_t *regs;
- bool wasup;
- uint corerev;
- uint32 coreinfo;
- uint memsize = 0;
- /* Block ints and save current core */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- /* Switch to SOCRAM core */
- if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
- goto done;
- /* Get info for determining size */
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, 0, 0);
- corerev = si_corerev(sih);
- coreinfo = R_REG(sii->osh, ®s->coreinfo);
- /* Calculate size from coreinfo based on rev */
- if (corerev == 0)
- memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
- else if (corerev < 3) {
- memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
- memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
- } else if ((corerev <= 7) || (corerev == 12)) {
- uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
- uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
- uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
- if (lss != 0)
- nb --;
- memsize = nb * (1 << (bsz + SR_BSZ_BASE));
- if (lss != 0)
- memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
- } else {
- uint8 i;
- uint nb;
- /* length of SRAM Banks increased for corerev greater than 23 */
- if (corerev >= 23) {
- nb = (coreinfo & (SRCI_SRNB_MASK | SRCI_SRNB_MASK_EXT)) >> SRCI_SRNB_SHIFT;
- } else {
- nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
- }
- for (i = 0; i < nb; i++)
- memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
- }
- /* Return to previous state and core */
- if (!wasup)
- si_core_disable(sih, 0);
- si_setcoreidx(sih, origidx);
- done:
- INTR_RESTORE(sii, intr_val);
- return memsize;
- }
- /** Return the TCM-RAM size of the ARMCR4 core. */
- uint32
- si_tcm_size(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- volatile uint8 *regs;
- bool wasup;
- uint32 corecap;
- uint memsize = 0;
- uint banku_size = 0;
- uint32 nab = 0;
- uint32 nbb = 0;
- uint32 totb = 0;
- uint32 bxinfo = 0;
- uint32 idx = 0;
- volatile uint32 *arm_cap_reg;
- volatile uint32 *arm_bidx;
- volatile uint32 *arm_binfo;
- /* Block ints and save current core */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- /* Switch to CR4 core */
- if (!(regs = si_setcore(sih, ARMCR4_CORE_ID, 0)))
- goto done;
- /* Get info for determining size. If in reset, come out of reset,
- * but remain in halt
- */
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, SICF_CPUHALT, SICF_CPUHALT);
- arm_cap_reg = (volatile uint32 *)(regs + SI_CR4_CAP);
- corecap = R_REG(sii->osh, arm_cap_reg);
- nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
- nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
- totb = nab + nbb;
- arm_bidx = (volatile uint32 *)(regs + SI_CR4_BANKIDX);
- arm_binfo = (volatile uint32 *)(regs + SI_CR4_BANKINFO);
- for (idx = 0; idx < totb; idx++) {
- W_REG(sii->osh, arm_bidx, idx);
- bxinfo = R_REG(sii->osh, arm_binfo);
- if (bxinfo & ARMCR4_BUNITSZ_MASK) {
- banku_size = ARMCR4_BSZ_1K;
- } else {
- banku_size = ARMCR4_BSZ_8K;
- }
- memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * banku_size;
- }
- /* Return to previous state and core */
- if (!wasup)
- si_core_disable(sih, 0);
- si_setcoreidx(sih, origidx);
- done:
- INTR_RESTORE(sii, intr_val);
- return memsize;
- }
- bool
- si_has_flops(si_t *sih)
- {
- uint origidx, cr4_rev;
- /* Find out CR4 core revision */
- origidx = si_coreidx(sih);
- if (si_setcore(sih, ARMCR4_CORE_ID, 0)) {
- cr4_rev = si_corerev(sih);
- si_setcoreidx(sih, origidx);
- if (cr4_rev == 1 || cr4_rev >= 3)
- return TRUE;
- }
- return FALSE;
- }
- uint32
- si_socram_srmem_size(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- sbsocramregs_t *regs;
- bool wasup;
- uint corerev;
- uint32 coreinfo;
- uint memsize = 0;
- if (CHIPID(sih->chip) == BCM43430_CHIP_ID ||
- CHIPID(sih->chip) == BCM43018_CHIP_ID) {
- return (64 * 1024);
- }
- /* Block ints and save current core */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- /* Switch to SOCRAM core */
- if (!(regs = si_setcore(sih, SOCRAM_CORE_ID, 0)))
- goto done;
- /* Get info for determining size */
- if (!(wasup = si_iscoreup(sih)))
- si_core_reset(sih, 0, 0);
- corerev = si_corerev(sih);
- coreinfo = R_REG(sii->osh, ®s->coreinfo);
- /* Calculate size from coreinfo based on rev */
- if (corerev >= 16) {
- uint8 i;
- uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
- for (i = 0; i < nb; i++) {
- W_REG(sii->osh, ®s->bankidx, i);
- if (R_REG(sii->osh, ®s->bankinfo) & SOCRAM_BANKINFO_RETNTRAM_MASK)
- memsize += socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
- }
- }
- /* Return to previous state and core */
- if (!wasup)
- si_core_disable(sih, 0);
- si_setcoreidx(sih, origidx);
- done:
- INTR_RESTORE(sii, intr_val);
- return memsize;
- }
- #if !defined(_CFEZ_) || defined(CFG_WL)
- void
- si_btcgpiowar(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- uint origidx;
- uint intr_val = 0;
- chipcregs_t *cc;
- /* Make sure that there is ChipCommon core present &&
- * UART_TX is strapped to 1
- */
- if (!(sih->cccaps & CC_CAP_UARTGPIO))
- return;
- /* si_corereg cannot be used as we have to guarantee 8-bit read/writes */
- INTR_OFF(sii, intr_val);
- origidx = si_coreidx(sih);
- cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
- ASSERT(cc != NULL);
- W_REG(sii->osh, &cc->uart0mcr, R_REG(sii->osh, &cc->uart0mcr) | 0x04);
- /* restore the original index */
- si_setcoreidx(sih, origidx);
- INTR_RESTORE(sii, intr_val);
- }
- void
- si_chipcontrl_restore(si_t *sih, uint32 val)
- {
- si_info_t *sii = SI_INFO(sih);
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
- }
- W_REG(sii->osh, &cc->chipcontrol, val);
- si_setcoreidx(sih, origidx);
- }
- uint32
- si_chipcontrl_read(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
- uint32 val;
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return -1;
- }
- val = R_REG(sii->osh, &cc->chipcontrol);
- si_setcoreidx(sih, origidx);
- return val;
- }
- /** switch muxed pins, on: SROM, off: FEMCTRL. Called for a family of ac chips, not just 4360. */
- void
- si_chipcontrl_srom4360(si_t *sih, bool on)
- {
- si_info_t *sii = SI_INFO(sih);
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
- uint32 val;
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
- }
- val = R_REG(sii->osh, &cc->chipcontrol);
- if (on) {
- val &= ~(CCTRL4360_SECI_MODE |
- CCTRL4360_BTSWCTRL_MODE |
- CCTRL4360_EXTRA_FEMCTRL_MODE |
- CCTRL4360_BT_LGCY_MODE |
- CCTRL4360_CORE2FEMCTRL4_ON);
- W_REG(sii->osh, &cc->chipcontrol, val);
- } else {
- }
- si_setcoreidx(sih, origidx);
- }
- /**
- * The SROM clock is derived from the backplane clock. 4365 (200Mhz) and 43684 (240Mhz) have a fast
- * backplane clock that requires a higher-than-POR-default clock divisor ratio for the SROM clock.
- */
- void
- si_srom_clk_set(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
- uint32 val;
- uint32 divisor = 1;
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
- }
- val = R_REG(sii->osh, &cc->clkdiv2);
- if (BCM4365_CHIP(sih->chip)) {
- divisor = CLKD2_SROMDIV_192; /* divide 200 by 192 -> SPROM clock ~ 1.04Mhz */
- } else {
- ASSERT(0);
- }
- W_REG(sii->osh, &cc->clkdiv2, ((val & ~CLKD2_SROM) | divisor));
- si_setcoreidx(sih, origidx);
- }
- #endif // endif
- void
- si_pmu_avb_clk_set(si_t *sih, osl_t *osh, bool set_flag)
- {
- }
- void
- si_btc_enable_chipcontrol(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
- if ((cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0)) == NULL) {
- SI_ERROR(("%s: Failed to find CORE ID!\n", __FUNCTION__));
- return;
- }
- /* BT fix */
- W_REG(sii->osh, &cc->chipcontrol,
- R_REG(sii->osh, &cc->chipcontrol) | CC_BTCOEX_EN_MASK);
- si_setcoreidx(sih, origidx);
- }
- /** cache device removed state */
- void si_set_device_removed(si_t *sih, bool status)
- {
- si_info_t *sii = SI_INFO(sih);
- sii->device_removed = status;
- }
- /** check if the device is removed */
- bool
- si_deviceremoved(si_t *sih)
- {
- uint32 w;
- si_info_t *sii = SI_INFO(sih);
- if (sii->device_removed) {
- return TRUE;
- }
- switch (BUSTYPE(sih->bustype)) {
- case PCI_BUS:
- ASSERT(SI_INFO(sih)->osh != NULL);
- w = OSL_PCI_READ_CONFIG(SI_INFO(sih)->osh, PCI_CFG_VID, sizeof(uint32));
- if ((w & 0xFFFF) != VENDOR_BROADCOM)
- return TRUE;
- break;
- }
- return FALSE;
- }
- bool
- si_is_warmboot(void)
- {
- #ifdef BCMULP
- return (boot_type == WARM_BOOT);
- #else
- return FALSE;
- #endif // endif
- }
- bool
- si_is_sprom_available(si_t *sih)
- {
- if (CCREV(sih->ccrev) >= 31) {
- si_info_t *sii;
- uint origidx;
- chipcregs_t *cc;
- uint32 sromctrl;
- if ((sih->cccaps & CC_CAP_SROM) == 0)
- return FALSE;
- sii = SI_INFO(sih);
- origidx = sii->curidx;
- cc = si_setcoreidx(sih, SI_CC_IDX);
- ASSERT(cc);
- sromctrl = R_REG(sii->osh, &cc->sromcontrol);
- si_setcoreidx(sih, origidx);
- return (sromctrl & SRC_PRESENT);
- }
- switch (CHIPID(sih->chip)) {
- case BCM43018_CHIP_ID:
- case BCM43430_CHIP_ID:
- return FALSE;
- case BCM4335_CHIP_ID:
- CASE_BCM4345_CHIP:
- return ((sih->chipst & CST4335_SPROM_MASK) &&
- !(sih->chipst & CST4335_SFLASH_MASK));
- case BCM4349_CHIP_GRPID:
- return (sih->chipst & CST4349_SPROM_PRESENT) != 0;
- case BCM53573_CHIP_GRPID:
- return FALSE; /* SPROM PRESENT is not defined for 53573 as of now */
- case BCM4364_CHIP_ID:
- return (sih->chipst & CST4364_SPROM_PRESENT) != 0;
- case BCM4369_CHIP_GRPID:
- if (CHIPREV(sih->chiprev) == 0) {
- /* WAR for 4369a0: HW4369-1729. no sprom, default to otp always. */
- return 0;
- } else {
- return (sih->chipst & CST4369_SPROM_PRESENT) != 0;
- }
- #ifdef CHIPS_CUSTOMER_HW6
- case BCM4368_CHIP_ID:
- return FALSE;
- #endif /* CHIPS_CUSTOMER_HW6 */
- case BCM4347_CHIP_GRPID:
- return (sih->chipst & CST4347_SPROM_PRESENT) != 0;
- break;
- case BCM4350_CHIP_ID:
- case BCM4354_CHIP_ID:
- case BCM43556_CHIP_ID:
- case BCM43558_CHIP_ID:
- case BCM43566_CHIP_ID:
- case BCM43568_CHIP_ID:
- case BCM43569_CHIP_ID:
- case BCM43570_CHIP_ID:
- case BCM4358_CHIP_ID:
- return (sih->chipst & CST4350_SPROM_PRESENT) != 0;
- CASE_BCM43602_CHIP:
- return (sih->chipst & CST43602_SPROM_PRESENT) != 0;
- case BCM43131_CHIP_ID:
- case BCM43217_CHIP_ID:
- case BCM43428_CHIP_ID:
- return (sih->chipst & CST43228_OTP_PRESENT) != CST43228_OTP_PRESENT;
- case BCM4373_CHIP_ID:
- case BCM43012_CHIP_ID:
- return FALSE;
- default:
- return TRUE;
- }
- }
- uint32 si_get_sromctl(si_t *sih)
- {
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
- uint32 sromctl;
- osl_t *osh = si_osh(sih);
- cc = si_setcoreidx(sih, SI_CC_IDX);
- ASSERT((uintptr)cc);
- sromctl = R_REG(osh, &cc->sromcontrol);
- /* return to the original core */
- si_setcoreidx(sih, origidx);
- return sromctl;
- }
- int si_set_sromctl(si_t *sih, uint32 value)
- {
- chipcregs_t *cc;
- uint origidx = si_coreidx(sih);
- osl_t *osh = si_osh(sih);
- int ret = BCME_OK;
- cc = si_setcoreidx(sih, SI_CC_IDX);
- ASSERT((uintptr)cc);
- /* get chipcommon rev */
- if (si_corerev(sih) >= 32) {
- /* SpromCtrl is only accessible if CoreCapabilities.SpromSupported and
- * SpromPresent is 1.
- */
- if ((R_REG(osh, &cc->capabilities) & CC_CAP_SROM) != 0 &&
- (R_REG(osh, &cc->sromcontrol) & SRC_PRESENT)) {
- W_REG(osh, &cc->sromcontrol, value);
- } else {
- ret = BCME_NODEVICE;
- }
- } else {
- ret = BCME_UNSUPPORTED;
- }
- /* return to the original core */
- si_setcoreidx(sih, origidx);
- return ret;
- }
- uint
- si_core_wrapperreg(si_t *sih, uint32 coreidx, uint32 offset, uint32 mask, uint32 val)
- {
- uint origidx, intr_val = 0;
- uint ret_val;
- si_info_t *sii = SI_INFO(sih);
- origidx = si_coreidx(sih);
- INTR_OFF(sii, intr_val);
- si_setcoreidx(sih, coreidx);
- ret_val = si_wrapperreg(sih, offset, mask, val);
- /* return to the original core */
- si_setcoreidx(sih, origidx);
- INTR_RESTORE(sii, intr_val);
- return ret_val;
- }
- /* cleanup the timer from the host when ARM is been halted
- * without a chance for ARM cleanup its resources
- * If left not cleanup, Intr from a software timer can still
- * request HT clk when ARM is halted.
- */
- uint32
- si_pmu_res_req_timer_clr(si_t *sih)
- {
- uint32 mask;
- mask = PRRT_REQ_ACTIVE | PRRT_INTEN | PRRT_HT_REQ;
- mask <<= 14;
- /* clear mask bits */
- pmu_corereg(sih, SI_CC_IDX, res_req_timer, mask, 0);
- /* readback to ensure write completes */
- return pmu_corereg(sih, SI_CC_IDX, res_req_timer, 0, 0);
- }
- /** turn on/off rfldo */
- void
- si_pmu_rfldo(si_t *sih, bool on)
- {
- }
- /* Caller of this function should make sure is on PCIE core
- * Used in pciedev.c.
- */
- void
- si_pcie_disable_oobselltr(si_t *sih)
- {
- ASSERT(si_coreid(sih) == PCIE2_CORE_ID);
- if (PCIECOREREV(sih->buscorerev) >= 23)
- si_wrapperreg(sih, AI_OOBSELIND74, ~0, 0);
- else
- si_wrapperreg(sih, AI_OOBSELIND30, ~0, 0);
- }
- void
- si_pcie_ltr_war(si_t *sih)
- {
- }
- void
- si_pcie_hw_LTR_war(si_t *sih)
- {
- }
- void
- si_pciedev_reg_pm_clk_period(si_t *sih)
- {
- }
- void
- si_pciedev_crwlpciegen2(si_t *sih)
- {
- }
- void
- si_pcie_prep_D3(si_t *sih, bool enter_D3)
- {
- }
- #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
- uint32
- si_clear_backplane_to_per_core(si_t *sih, uint coreid, uint coreunit, void * wrap)
- {
- if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS)) {
- return ai_clear_backplane_to_per_core(sih, coreid, coreunit, wrap);
- }
- return AXI_WRAP_STS_NONE;
- }
- #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
- uint32
- si_clear_backplane_to(si_t *sih)
- {
- if ((CHIPTYPE(sih->socitype) == SOCI_AI) ||
- (CHIPTYPE(sih->socitype) == SOCI_DVTBUS)) {
- return ai_clear_backplane_to(sih);
- }
- return 0;
- }
- void
- si_update_backplane_timeouts(si_t *sih, bool enable, uint32 timeout_exp, uint32 cid)
- {
- #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
- /* Enable only for AXI */
- if (CHIPTYPE(sih->socitype) != SOCI_AI) {
- return;
- }
- ai_update_backplane_timeouts(sih, enable, timeout_exp, cid);
- #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
- }
- /*
- * This routine adds the AXI timeouts for
- * chipcommon, pcie and ARM slave wrappers
- */
- void
- si_slave_wrapper_add(si_t *sih)
- {
- #if defined(AXI_TIMEOUTS) || defined(BCM_BACKPLANE_TIMEOUT)
- uint32 axi_to = 0;
- /* Enable only for AXI */
- if ((CHIPTYPE(sih->socitype) != SOCI_AI) &&
- (CHIPTYPE(sih->socitype) != SOCI_DVTBUS)) {
- return;
- }
- if (CHIPID(sih->chip) == BCM4345_CHIP_ID && CHIPREV(sih->chiprev) >= 6) {
- si_info_t *sii = SI_INFO(sih);
- int wrapper_idx = (int)sii->axi_num_wrappers - 1;
- ASSERT(wrapper_idx >= 0); /* axi_wrapper[] not initialised */
- do {
- if (sii->axi_wrapper[wrapper_idx].wrapper_type == AI_SLAVE_WRAPPER &&
- sii->axi_wrapper[wrapper_idx].cid == 0xfff) {
- sii->axi_wrapper[wrapper_idx].wrapper_addr = 0x1810b000;
- break;
- }
- } while (wrapper_idx-- > 0);
- ASSERT(wrapper_idx >= 0); /* all addresses valid for the chiprev under test */
- }
- if (BCM4347_CHIP(sih->chip)) {
- axi_to = AXI_TO_VAL_4347;
- }
- else {
- axi_to = AXI_TO_VAL;
- }
- /* All required slave wrappers are added in ai_scan */
- ai_update_backplane_timeouts(sih, TRUE, axi_to, 0);
- #ifdef DISABLE_PCIE2_AXI_TIMEOUT
- ai_update_backplane_timeouts(sih, FALSE, 0, PCIE_CORE_ID);
- ai_update_backplane_timeouts(sih, FALSE, 0, PCIE2_CORE_ID);
- #endif // endif
- #endif /* AXI_TIMEOUTS || BCM_BACKPLANE_TIMEOUT */
- }
- void
- si_pll_sr_reinit(si_t *sih)
- {
- }
- /* Programming d11 core oob settings for 4364
- * WARs for HW4364-237 and HW4364-166
- */
- void
- si_config_4364_d11_oob(si_t *sih, uint coreid)
- {
- uint save_idx;
- save_idx = si_coreidx(sih);
- si_setcore(sih, coreid, 0);
- si_wrapperreg(sih, AI_OOBSELINC30, ~0, 0x81828180);
- si_wrapperreg(sih, AI_OOBSELINC74, ~0, 0x87868183);
- si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, 0x84858484);
- si_setcore(sih, coreid, 1);
- si_wrapperreg(sih, AI_OOBSELINC30, ~0, 0x81828180);
- si_wrapperreg(sih, AI_OOBSELINC74, ~0, 0x87868184);
- si_wrapperreg(sih, AI_OOBSELOUTB74, ~0, 0x84868484);
- si_setcoreidx(sih, save_idx);
- }
- void
- si_pll_closeloop(si_t *sih)
- {
- #if defined(SAVERESTORE)
- uint32 data;
- /* disable PLL open loop operation */
- switch (CHIPID(sih->chip)) {
- #ifdef SAVERESTORE
- case BCM43018_CHIP_ID:
- case BCM43430_CHIP_ID:
- if (SR_ENAB() && sr_isenab(sih)) {
- /* read back the pll openloop state */
- data = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8, 0, 0);
- /* current mode is openloop (possible POR) */
- if ((data & PMU1_PLLCTL8_OPENLOOP_MASK) != 0) {
- si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL8,
- PMU1_PLLCTL8_OPENLOOP_MASK, 0);
- si_pmu_pllupd(sih);
- }
- }
- break;
- #endif /* SAVERESTORE */
- case BCM4347_CHIP_GRPID:
- case BCM4369_CHIP_GRPID:
- si_pmu_chipcontrol(sih, PMU_CHIPCTL1,
- PMU_CC1_ENABLE_CLOSED_LOOP_MASK, PMU_CC1_ENABLE_CLOSED_LOOP);
- break;
- default:
- /* any unsupported chip bail */
- return;
- }
- #endif // endif
- }
- #if defined(BCMSRPWR) && !defined(BCMSRPWR_DISABLED)
- bool _bcmsrpwr = TRUE;
- #else
- bool _bcmsrpwr = FALSE;
- #endif // endif
- #define PWRREQ_OFFSET(sih) OFFSETOF(chipcregs_t, powerctl)
- static void
- si_corereg_pciefast_write(si_t *sih, uint regoff, uint val)
- {
- volatile uint32 *r = NULL;
- si_info_t *sii = SI_INFO(sih);
- ASSERT((BUSTYPE(sih->bustype) == PCI_BUS));
- r = (volatile uint32 *)((volatile char *)sii->curmap +
- PCI_16KB0_PCIREGS_OFFSET + regoff);
- W_REG(sii->osh, r, val);
- }
- static uint
- si_corereg_pciefast_read(si_t *sih, uint regoff)
- {
- volatile uint32 *r = NULL;
- si_info_t *sii = SI_INFO(sih);
- ASSERT((BUSTYPE(sih->bustype) == PCI_BUS));
- r = (volatile uint32 *)((volatile char *)sii->curmap +
- PCI_16KB0_PCIREGS_OFFSET + regoff);
- return R_REG(sii->osh, r);
- }
- uint32
- si_srpwr_request(si_t *sih, uint32 mask, uint32 val)
- {
- uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
- OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
- uint32 mask2 = mask;
- uint32 val2 = val;
- volatile uint32 *fast_srpwr_addr = (volatile uint32 *)((uintptr)SI_ENUM_BASE(sih)
- + (uintptr)offset);
- if (mask || val) {
- mask <<= SRPWR_REQON_SHIFT;
- val <<= SRPWR_REQON_SHIFT;
- /* Return if requested power request is already set */
- if (BUSTYPE(sih->bustype) == SI_BUS) {
- r = R_REG(OSH_NULL, fast_srpwr_addr);
- } else {
- r = si_corereg_pciefast_read(sih, offset);
- }
- if ((r & mask) == val) {
- return r;
- }
- r = (r & ~mask) | val;
- if (BUSTYPE(sih->bustype) == SI_BUS) {
- W_REG(OSH_NULL, fast_srpwr_addr, r);
- r = R_REG(OSH_NULL, fast_srpwr_addr);
- } else {
- si_corereg_pciefast_write(sih, offset, r);
- r = si_corereg_pciefast_read(sih, offset);
- }
- if (val2) {
- if ((r & (mask2 << SRPWR_STATUS_SHIFT)) ==
- (val2 << SRPWR_STATUS_SHIFT)) {
- return r;
- }
- si_srpwr_stat_spinwait(sih, mask2, val2);
- }
- } else {
- if (BUSTYPE(sih->bustype) == SI_BUS) {
- r = R_REG(OSH_NULL, fast_srpwr_addr);
- } else {
- r = si_corereg_pciefast_read(sih, offset);
- }
- }
- return r;
- }
- uint32
- si_srpwr_stat_spinwait(si_t *sih, uint32 mask, uint32 val)
- {
- uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
- OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
- volatile uint32 *fast_srpwr_addr = (volatile uint32 *)((uintptr)SI_ENUM_BASE(sih)
- + (uintptr)offset);
- ASSERT(mask);
- ASSERT(val);
- /* spinwait on pwrstatus */
- mask <<= SRPWR_STATUS_SHIFT;
- val <<= SRPWR_STATUS_SHIFT;
- if (BUSTYPE(sih->bustype) == SI_BUS) {
- SPINWAIT(((R_REG(OSH_NULL, fast_srpwr_addr) & mask) != val),
- PMU_MAX_TRANSITION_DLY);
- r = R_REG(OSH_NULL, fast_srpwr_addr) & mask;
- ASSERT(r == val);
- } else {
- SPINWAIT(((si_corereg_pciefast_read(sih, offset) & mask) != val),
- PMU_MAX_TRANSITION_DLY);
- r = si_corereg_pciefast_read(sih, offset) & mask;
- ASSERT(r == val);
- }
- r = (r >> SRPWR_STATUS_SHIFT) & SRPWR_DMN_ALL_MASK(sih);
- return r;
- }
- uint32
- si_srpwr_stat(si_t *sih)
- {
- uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
- OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
- uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
- if (BUSTYPE(sih->bustype) == SI_BUS) {
- r = si_corereg(sih, cidx, offset, 0, 0);
- } else {
- r = si_corereg_pciefast_read(sih, offset);
- }
- r = (r >> SRPWR_STATUS_SHIFT) & SRPWR_DMN_ALL_MASK(sih);
- return r;
- }
- uint32
- si_srpwr_domain(si_t *sih)
- {
- uint32 r, offset = (BUSTYPE(sih->bustype) == SI_BUS) ?
- OFFSETOF(chipcregs_t, powerctl) : PWRREQ_OFFSET(sih);
- uint cidx = (BUSTYPE(sih->bustype) == SI_BUS) ? SI_CC_IDX : sih->buscoreidx;
- if (BUSTYPE(sih->bustype) == SI_BUS) {
- r = si_corereg(sih, cidx, offset, 0, 0);
- } else {
- r = si_corereg_pciefast_read(sih, offset);
- }
- r = (r >> SRPWR_DMN_ID_SHIFT) & SRPWR_DMN_ID_MASK;
- return r;
- }
- uint32
- si_srpwr_domain_all_mask(si_t *sih)
- {
- uint32 mask = SRPWR_DMN0_PCIE_MASK |
- SRPWR_DMN1_ARMBPSD_MASK |
- SRPWR_DMN2_MACAUX_MASK |
- SRPWR_DMN3_MACMAIN_MASK;
- if (si_scan_core_present(sih)) {
- mask |= SRPWR_DMN4_MACSCAN_MASK;
- }
- return mask;
- }
- /* Utility API to read/write the raw registers with absolute address.
- * This function can be invoked from either FW or host driver.
- */
- uint32
- si_raw_reg(si_t *sih, uint32 reg, uint32 val, uint32 wrire_req)
- {
- si_info_t *sii = SI_INFO(sih);
- uint32 address_space = reg & ~0xFFF;
- volatile uint32 * addr = (void*)(uintptr)(reg);
- uint32 prev_value = 0;
- uint32 cfg_reg = 0;
- if (sii == NULL) {
- return 0;
- }
- /* No need to translate the absolute address on SI bus */
- if (BUSTYPE(sih->bustype) == SI_BUS) {
- goto skip_cfg;
- }
- /* This API supports only the PCI host interface */
- if (BUSTYPE(sih->bustype) != PCI_BUS) {
- return ID32_INVALID;
- }
- if (PCIE_GEN2(sii)) {
- /* Use BAR0 Secondary window is PCIe Gen2.
- * Set the secondary BAR0 Window to current register of interest
- */
- addr = (volatile uint32*)(((volatile uint8*)sii->curmap) +
- PCI_SEC_BAR0_WIN_OFFSET + (reg & 0xfff));
- cfg_reg = PCIE2_BAR0_CORE2_WIN;
- } else {
- /* PCIe Gen1 do not have secondary BAR0 window.
- * reuse the BAR0 WIN2
- */
- addr = (volatile uint32*)(((volatile uint8*)sii->curmap) +
- PCI_BAR0_WIN2_OFFSET + (reg & 0xfff));
- cfg_reg = PCI_BAR0_WIN2;
- }
- prev_value = OSL_PCI_READ_CONFIG(sii->osh, cfg_reg, 4);
- if (prev_value != address_space) {
- OSL_PCI_WRITE_CONFIG(sii->osh, cfg_reg,
- sizeof(uint32), address_space);
- } else {
- prev_value = 0;
- }
- skip_cfg:
- if (wrire_req) {
- W_REG(sii->osh, addr, val);
- } else {
- val = R_REG(sii->osh, addr);
- }
- if (prev_value) {
- /* Restore BAR0 WIN2 for PCIE GEN1 devices */
- OSL_PCI_WRITE_CONFIG(sii->osh,
- cfg_reg, sizeof(uint32), prev_value);
- }
- return val;
- }
- uint8
- si_lhl_ps_mode(si_t *sih)
- {
- si_info_t *sii = SI_INFO(sih);
- return sii->lhl_ps_mode;
- }
- bool
- BCMRAMFN(si_scan_core_present)(si_t *sih)
- {
- return ((si_numcoreunits(sih, D11_CORE_ID) >= 2) &&
- (si_numcoreunits(sih, SR_CORE_ID) > 4));
- }
|