123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532 |
- /**
- * @file hal_sdhost.c
- * @author ALLWINNERTECH IOT WLAN Team
- */
- /*
- * Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, )|hhst->sdio_irq_maskPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "_sdhost.h"
- #include "sunxi_hal_common.h"
- #include "stdint.h"
- //#include "io.h"
- //#include "hal_prcm.h"
- #include "hal_ccm.h"
- #include "hal_gpio.h"
- #include "hal_board.h"
- #include "hal_dev.h"
- #include "hal_clock.h"
- #include "sdmmc/sys/param.h"
- #include "hal_sdhost.h"
- #ifdef CONFIG_USE_SDIO
- #include "sdio.h"
- #endif
- #include "sdmmc.h"
- #include "_sd_define.h"
- #include "_core.h"
- #ifndef CONFIG_KERNEL_FREERTOS
- #include "osal/os/RT-Thread/os_util.h"
- #else
- #include "osal/os/FreeRTOS/os_util.h"
- #endif
- #include "interrupt.h"
- //#include "k_arch.h"
- extern uint32_t sdmmc_pinctrl_init(struct mmc_host *host);
- extern int mmc_gpiod_request_cd_irq(struct mmc_host* host);
- //#define __dsb__() dsb(0xf)
- #ifndef UINT_MAX
- #define UINT_MAX (~0U)
- #endif
- /*
- #define SDC_REQUEST_IRQ(n, hdl) HAL_NVIC_SetIRQHandler(n, hdl)
- #define SDC_SetPriority(n, l) HAL_NVIC_SetPriority(n, l)
- #define SDC_ENABLE_IRQ(n) HAL_NVIC_EnableIRQ(n)
- #define SDC_CONFIG_IRQ(n, hdl, l) HAL_NVIC_ConfigExtIRQ(n, hdl, l)
- #define SDC_DISABLE_IRQ(n) HAL_NVIC_DisableIRQ(n)
- #define SDC_CLEAR_IRQPINGD(n) HAL_NVIC_ClearPendingIRQ(n)
- #define SDC_IRQHandler NVIC_IRQHandler
- */
- #define SDC_REQUEST_IRQ(n, hdl,d) ({SDC_LOGD("%s,%d,sdc %d irq request \n",__func__, __LINE__, d->sdc_id);\
- request_irq(n, hdl, 0, "sdmmc",d);})
- #define SDC_FREE_IRQ(n, d) (free_irq(n, d))
- #define SDC_SetPriority(n, l) ({SDC_LOGN("Not imp %s,%d\n", __FUNCTION__,__LINE__);})
- #define SDC_ENABLE_IRQ(n) enable_irq(n)
- #define SDC_CONFIG_IRQ(n, hdl, l) ({SDC_LOGN("Not imp %s,%d\n", __FUNCTION__,__LINE__);})
- #define SDC_DISABLE_IRQ(n) disable_irq(n)
- //#define SDC_CLEAR_IRQPINGD(n) gic_clear_pending(n)
- #define SDC_CLEAR_IRQPINGD(n) ({SDC_LOGN("Not imp %s,%d\n", __FUNCTION__,__LINE__);})
- //#define SDC_CLEAR_IRQPINGD(n) free_irq(n)
- //#define SDC_IRQHandler interrupt_handler_t
- #define SDC_IRQHandler irq_handler_t *
- #define NUSE_STANDARD_INTERFACE 1
- #ifdef NUSE_STANDARD_INTERFACE
- #define SDC1_SUPPORT 1
- #define SDC_CCM_SDC0_SCLK_CTRL (SDC_CCM_BASE + 0x830)
- #define SDC_CCM_SDC1_SCLK_CTRL (SDC_CCM_BASE + 0x834)
- #define SDC_CCM_SDC_BUS_GATE_RESET (SDC_CCM_BASE + 0x84c)
- /*
- #define SDC0_CCM_BusForceReset() HAL_CCM_BusForcePeriphReset(CCM_BUS_PERIPH_BIT_SDC0)
- #define SDC0_CCM_BusReleaseRest() HAL_CCM_BusReleasePeriphReset(CCM_BUS_PERIPH_BIT_SDC0)
- #define SDC0_CCM_BusEnableClock() HAL_CCM_BusEnablePeriphClock(CCM_BUS_PERIPH_BIT_SDC0)
- #define SDC0_CCM_BusDisableClock() HAL_CCM_BusDisablePeriphClock(CCM_BUS_PERIPH_BIT_SDC0)
- #define SDC0_CCM_EnableMClock() HAL_CCM_SDC0_EnableMClock()
- #define SDC0_DisableMClock HAL_CCM_SDC0_DisableMClock
- #define SDC0_SetMClock HAL_CCM_SDC0_SetMClock
- */
- #define SDC0_CCM_BusForceReset() ({int v = readl(SDC_CCM_SDC_BUS_GATE_RESET); v &= ~(1<<16); writel(v,SDC_CCM_SDC_BUS_GATE_RESET);})
- #define SDC0_CCM_BusReleaseRest() ({int v = readl(SDC_CCM_SDC_BUS_GATE_RESET); v |= (1<<16); writel(v,SDC_CCM_SDC_BUS_GATE_RESET);})
- #define SDC0_CCM_BusEnableClock() ({int v = readl(SDC_CCM_SDC_BUS_GATE_RESET); v |= (1<<0); writel(v,SDC_CCM_SDC_BUS_GATE_RESET);})
- #define SDC0_CCM_BusDisableClock() ({int v = readl(SDC_CCM_SDC_BUS_GATE_RESET); v &= ~(1<<0); writel(v,SDC_CCM_SDC_BUS_GATE_RESET);})
- #define SDC0_CCM_EnableMClock() ({int v = readl(SDC_CCM_SDC0_SCLK_CTRL); v |= (1<<31); writel(v,SDC_CCM_SDC0_SCLK_CTRL);})
- #define SDC0_DisableMClock() ({int v = readl(SDC_CCM_SDC0_SCLK_CTRL); v &= ~(1<<31); writel(v,SDC_CCM_SDC0_SCLK_CTRL);})
- #define SDC1_CCM_BusForceReset() ({int v = readl(SDC_CCM_SDC_BUS_GATE_RESET); v &= ~(1<<17); writel(v,SDC_CCM_SDC_BUS_GATE_RESET);})
- #define SDC1_CCM_BusReleaseRest() ({int v = readl(SDC_CCM_SDC_BUS_GATE_RESET); v |= (1<<17); writel(v,SDC_CCM_SDC_BUS_GATE_RESET);})
- #define SDC1_CCM_BusEnableClock() ({int v = readl(SDC_CCM_SDC_BUS_GATE_RESET); v |= (1<<1); writel(v,SDC_CCM_SDC_BUS_GATE_RESET);})
- #define SDC1_CCM_BusDisableClock() ({int v = readl(SDC_CCM_SDC_BUS_GATE_RESET); v &= ~(1<<1); writel(v,SDC_CCM_SDC_BUS_GATE_RESET);})
- #define SDC1_CCM_EnableMClock() ({int v = readl(SDC_CCM_SDC1_SCLK_CTRL); v |= (1<<31); writel(v,SDC_CCM_SDC1_SCLK_CTRL);})
- #define SDC1_DisableMClock() ({int v = readl(SDC_CCM_SDC1_SCLK_CTRL); v &= ~(1<<31); writel(v,SDC_CCM_SDC1_SCLK_CTRL);})
- #define SDC1_SET_GPIO_MUX() ({int v = readl(SDC_GPIO_BASE + 0xd8);\
- SDC_LOGD("RAW SET SDC1 MUX\n");\
- v &= ~(0xffffff); v |=0x222222;\
- writel(v,SDC_GPIO_BASE + 0xd8);\
- SDC_LOGD("RAW SDC1 MUX %x\n", readl(SDC_GPIO_BASE + 0xd8));})
- #define SDC1_SET_GPIO_DRV() ({int v = readl(SDC_GPIO_BASE + 0xec);\
- SDC_LOGD("RAW SET SDC1 DRV\n");\
- v &= ~(0xfff);\
- v |=0x000; writel(v,SDC_GPIO_BASE + 0xec);\
- SDC_LOGD("RAW SDC1 DRV %x\n",readl(SDC_GPIO_BASE + 0xec));})
- #define SDC1_SET_GPIO_PULL() ({int v = readl(SDC_GPIO_BASE + 0xf4);\
- SDC_LOGD("RAW SET SDC1 PULL\n");\
- v &= ~(0xfff);\
- v |=0x555; writel(v,SDC_GPIO_BASE + 0xf4);\
- SDC_LOGD("RAW SDC1 PULL %x\n",readl(SDC_GPIO_BASE + 0xf4));})
- #define SDC_TIG_SET_GPIO_MUX() ({int v = readl(SDC_GPIO_BASE + 0x28);\
- SDC_LOGD("+RAW SET TIG SDC MUX %x\n", SDC_GPIO_BASE + 0x28);\
- v &= ~(0x0000F000); v |=0x00001000;\
- writel(v,SDC_GPIO_BASE + 0x28);\
- SDC_LOGD("-RAW SDC TIG MUX %x\n", readl(SDC_GPIO_BASE + 0x28));})
- #define SDC_TIG_SET_GPIO_DRV() ({int v = readl(SDC_GPIO_BASE + 0x38);\
- SDC_LOGD("+RAW SET SDC TIG DRV %x\n", SDC_GPIO_BASE + 0x38);\
- v &= ~(0x00C00000);\
- v |=0x00C00000; writel(v,SDC_GPIO_BASE + 0x38);\
- SDC_LOGD("-RAW SDC TRG DRV %x\n",readl(SDC_GPIO_BASE + 0x38));})
- #define SDC_TIG_SET_GPIO_PULL() ({int v = readl(SDC_GPIO_BASE + 0x40);\
- SDC_LOGD("+RAW SET SDC TRG PULL %x\n", SDC_GPIO_BASE + 0x40);\
- v &= ~(0x00C00000);\
- v |=0x00400000; writel(v,SDC_GPIO_BASE + 0x40);\
- SDC_LOGD("-RAW SDC1 PULL %x\n",readl(SDC_GPIO_BASE + 0x40));})
- #define SDC_TIG_SET_GPIO_DAT() ({int v = readl(SDC_GPIO_BASE + 0x34);\
- SDC_LOGD("+raw set sdc trg dat %x\n",SDC_GPIO_BASE + 0x34);\
- v &= ~(0x00000800);\
- v |=0x00000800; writel(v,SDC_GPIO_BASE + 0x34);\
- SDC_LOGD("-RAW SDC1 DAT %x\n",readl(SDC_GPIO_BASE + 0x34));})
- #define SDC_TIG_CLR_GPIO_DAT() ({int v = readl(SDC_GPIO_BASE + 0x34);\
- SDC_LOGD("RAW SET SDC TRG dat\n");\
- v &= ~(0x00000800);\
- v |=0x00000000; writel(v,SDC_GPIO_BASE + 0x34);\
- SDC_LOGD("RAW SDC1 dat %x\n",readl(SDC_GPIO_BASE + 0x34));})
- #define HAL_BoardIoctl(a,b,c) ({SDC_LOGN("NOT IMP %s,%d\n",__FUNCTION__, __LINE__);})
- #define HAL_GPIO_ReadPin(cd_gpios, data) ({hal_gpio_get_data(cd_gpios, (gpio_data_t *)data);\
- *(data);})
- #else
- #define SDC0_CCM_BusForceReset() HAL_CCM_BusForcePeriphReset(CCM_BUS_PERIPH_BIT_SDC0)
- #define SDC0_CCM_BusReleaseRest() HAL_CCM_BusReleasePeriphReset(CCM_BUS_PERIPH_BIT_SDC0)
- #define SDC0_CCM_BusEnableClock() HAL_CCM_BusEnablePeriphClock(CCM_BUS_PERIPH_BIT_SDC0)
- #define SDC0_CCM_BusDisableClock() HAL_CCM_BusDisablePeriphClock(CCM_BUS_PERIPH_BIT_SDC0)
- #define SDC0_CCM_EnableMClock() HAL_CCM_SDC0_EnableMClock()
- #define SDC0_DisableMClock HAL_CCM_SDC0_DisableMClock
- #define SDC0_SetMClock HAL_CCM_SDC0_SetMClock
- #define SDC1_SUPPORT 1
- #define SDC1_CCM_BusForceReset() HAL_CCM_BusForcePeriphReset(CCM_BUS_PERIPH_BIT_SDC1)
- #define SDC1_CCM_BusReleaseRest() HAL_CCM_BusReleasePeriphReset(CCM_BUS_PERIPH_BIT_SDC1)
- #define SDC1_CCM_BusEnableClock() HAL_CCM_BusEnablePeriphClock(CCM_BUS_PERIPH_BIT_SDC1)
- #define SDC1_CCM_BusDisableClock() HAL_CCM_BusDisablePeriphClock(CCM_BUS_PERIPH_BIT_SDC1)
- #define SDC1_CCM_EnableMClock() HAL_CCM_SDC1_EnableMClock()
- #define SDC1_DisableMClock HAL_CCM_SDC1_DisableMClock
- #define SDC1_SetMClock HAL_CCM_SDC1_SetMClock
- #endif /* NUSE_STANDARD_INTERFACE */
- #ifndef SDC1_SUPPORT
- #define SDC1_SUPPORT 0
- #endif
- #define MEMS_VA2PA(x) __va_to_pa(x)
- #if 0
- #define mci_readl(host, reg) \
- ({ uint32_t val;\
- SDC_LOGD("+reg add 0x%x\n", (uint32_t)(host)->reg_base + reg);\
- val = readl((uint32_t)(host)->reg_base + reg);\
- SDC_LOGD("%s,%d\n", __FUNCTION__, __LINE__);\
- SDC_LOGD("-reg val 0x%x\n", val);\
- val;})
- #define mci_writel(value, host, reg) \
- ({ uint32_t val;\
- SDC_LOGD("+reg add 0x%x write val 0x%x\n", (uint32_t)(host)->reg_base + reg, value);\
- writel((value), (uint32_t)(host)->reg_base + reg);\
- val = readl((uint32_t)(host)->reg_base + reg);\
- SDC_LOGD("%s,%d\n", __FUNCTION__, __LINE__);\
- SDC_LOGD("-reg read val 0x%x\n", val);})
- #define mci_readw(host, reg) \
- ({ uint32_t val;\
- SDC_LOGD("+reg add 0x%x\n", (uint32_t)(host)->reg_base + reg);\
- val = readw((uint32_t)(host)->reg_base + reg);\
- SDC_LOGD("%s,%d\n", __FUNCTION__, __LINE__);\
- SDC_LOGD("-reg val 0x%x\n", val);\
- val;})
- #define mci_writew(value, host, reg) \
- ({ uint32_t val;\
- SDC_LOGD("+reg add 0x%x write val 0x%x\n", (uint32_t)(host)->reg_base + reg, value);\
- writew((value), (uint32_t)(host)->reg_base + reg);\
- val = readl((uint32_t)(host)->reg_base + reg);\
- SDC_LOGD("%s,%d\n", __FUNCTION__, __LINE__);\
- SDC_LOGD("-reg read val 0x%x\n", val);})
- #define mci_readb(host, reg) \
- ({ uint32_t val;\
- SDC_LOGD("+reg add 0x%x\n", (uint32_t)(host)->reg_base + reg);\
- val = readb((uint32_t)(host)->reg_base + reg);\
- SDC_LOGD("%s,%d\n", __FUNCTION__, __LINE__);\
- SDC_LOGD("-reg val 0x%x\n", val);\
- val;})
- #define mci_writeb(value, host, reg) \
- ({ uint32_t val;\
- SDC_LOGD("+reg add 0x%x write val 0x%x\n", (uint32_t)(host)->reg_base + reg, value);\
- writeb((value), (uint32_t)(host)->reg_base + reg);\
- val = readl((uint32_t)(host)->reg_base + reg);\
- SDC_LOGD("%s,%d\n", __FUNCTION__, __LINE__);\
- SDC_LOGD("-reg read val 0x%x\n", val);})
- #else
- #define mci_readl(host, reg) \
- readl(HAL_PT_TO_U((host)->reg_base) + reg)
- #define mci_writel(value, host, reg) \
- writel((value), HAL_PT_TO_U((host)->reg_base) + reg)
- #define mci_writew(value, host, reg) \
- writew((value), HAL_PT_TO_U((host)->reg_base) + reg)
- #define mci_readw(host, reg) \
- readw(HAL_PT_TO_U((host)->reg_base) + reg)
- #define mci_readb(host, reg) \
- readb(HAL_PT_TO_U((host)->reg_base) + reg)
- #define mci_writeb(value, host, reg) \
- writeb((value),HAL_PT_TO_U((host)->reg_base) + reg)
- #endif
- #define SDC_BUSY_WAIT_LOOP (0xffffffff)
- int32_t __mci_check_bit_clear(struct mmc_host *host, uint32_t reg_offset, uint32_t bit_map);
- static struct mmc_host *_mci_host[SDC_NUM];
- /**
- * sdc timer timeout flags
- */
- static int __sdc_init_timeout_flags = 0;
- static uint64_t __mci_get_rate(uint64_t bytes, uint64_t time_us)
- {
- uint64_t ns;
- ns = time_us * 1000;
- bytes *= 1000000000;
- while (ns > UINT_MAX) {
- bytes >>= 1;
- ns >>= 1;
- }
- if (!ns)
- return 0;
- do_div(bytes, (uint32_t)ns);
- return bytes;
- }
- static void __mci_force_dump_host_info(struct mmc_host *host)
- {
- uint16_t debug_mask = host->debug_mask;
- host->debug_mask |= ROM_DUMP_MASK | ROM_ERR_MASK;
- SDC_LOGE("*force dump gpio reg*\n");
- sdc_hex_dump_word((void *)SDC_GPIO_BASE+0xb0,0xff);
- sdc_hex_dump_word((void *)SDC_GPIO_BASE+0x340,0xff);
- SDC_LOGE("*force dump ccmu reg*\n");
- sdc_hex_dump_word((void *)SDC_CCM_SDC0_SCLK_CTRL ,0xff);
- sdc_hex_dump_word((void *)SDC_CCM_BASE ,0xff);
- SDC_LOGE("*force dump smc reg*\n");
- sdc_hex_dump_word((void *)(SMC0_BASE + 0x1000UL * host->sdc_id) ,0x150);
- SDC_LOGE("force dump state wait:%x,int_sum %x, int_err %x\n",\
- (unsigned int)host->wait, (unsigned int)host->int_sum, (unsigned int)host->int_err);
- SDC_LOGE("force dump done dma_done:%x,transfer_done %x\n",\
- (unsigned int)host->dma_done, (unsigned int)host->trans_done);
- host->debug_mask = debug_mask;
- }
- static int32_t __mci_exit_host(struct mmc_host *host)
- {
- uint32_t rval;
- #ifdef CONFIG_SDC_SUPPORT_1V8
- host->voltage = SDC_WOLTAGE_OFF;
- #endif
- rval = mci_readl(host, SDXC_REG_GCTRL) | SDXC_HWReset;
- mci_writel(rval, host, SDXC_REG_GCTRL);
- __mci_check_bit_clear(host, SDXC_REG_GCTRL, SDXC_HWReset);
- return 0;
- }
- static __inline void __mci_sel_access_mode(struct mmc_host *host, uint32_t access_mode)
- {
- mci_writel((mci_readl(host, SDXC_REG_GCTRL) & (~SDXC_ACCESS_BY_AHB)) | access_mode,
- host, SDXC_REG_GCTRL);
- }
- static int32_t __mci_reset(struct mmc_host *host)
- {
- uint32_t value;
- uint32_t time = HAL_Ticks() + HAL_MSecsToTicks(1000) + 1;
- value = mci_readl(host, SDXC_REG_GCTRL)|SDXC_HWReset;
- mci_writel(value, host, SDXC_REG_GCTRL);
- while ((mci_readl(host, SDXC_REG_GCTRL) & SDXC_SoftReset) && (HAL_TimeBefore(HAL_Ticks(), time)));
- if (mci_readl(host, SDXC_REG_GCTRL) & SDXC_SoftReset) {
- SDC_LOGE("SDC reset time out\n");
- return -1;
- }
- SDC_LOGD("%s,%d SDC reset finish \n", __func__, __LINE__);
- return 0;
- }
- static int32_t __mci_program_clk(struct mmc_host *host)
- {
- uint32_t value;
- int32_t ret = 0;
- uint32_t time = HAL_Ticks() + HAL_MSecsToTicks(1000) + 1;
- /* disable command done interrupt */
- mci_writel((mci_readl(host, SDXC_REG_IMASK) & (~SDXC_CmdDone))|host->sdio_irq_mask,
- host, SDXC_REG_IMASK);
- mci_writel(mci_readl(host, SDXC_REG_CLKCR) | SDXC_Mask_Data0,\
- host, SDXC_REG_CLKCR);
- value = SDXC_Start | SDXC_UPCLKOnly | SDXC_WaitPreOver;
- mci_writel(value, host, SDXC_REG_CMDR);
- do {
- value = mci_readl(host, SDXC_REG_CMDR);
- } while ((value & SDXC_Start) && HAL_TimeBefore(HAL_Ticks(), time));
- if (mci_readl(host, SDXC_REG_CMDR) & SDXC_Start) {
- SDC_LOGE("%s,%d SDC change clock time out\n", __func__, __LINE__);
- __mci_force_dump_host_info(host);
- ret = -1;
- }
- /* clear command done flag */
- value = mci_readl(host, SDXC_REG_RINTR);
- mci_writel(value, host, SDXC_REG_RINTR);
- mci_writel(mci_readl(host, SDXC_REG_CLKCR) & ~SDXC_Mask_Data0,\
- host, SDXC_REG_CLKCR);
- /* enable command done interrupt */
- mci_writel((mci_readl(host, SDXC_REG_IMASK) | SDXC_CmdDone)|host->sdio_irq_mask,
- host, SDXC_REG_IMASK);
- return ret;
- }
- static void __mci_trans_by_ahb(struct mmc_host *host, struct mmc_data *data)
- {
- uint32_t i, j;
- uint32_t *buf_temp; /* Cortex-M3/4 can access data with unaligned address */
- uint32_t time;
- for (i = 0; i < data->sg_len; i++) {
- buf_temp = data->sg[i].buffer;
- if (data->flags & MMC_DATA_READ) {
- for (j = 0; j < (data->sg[i].len >> 2); j++) { /* sg[i].len should be multiply of 4 */
- time = HAL_Ticks() + HAL_MSecsToTicks(1000) + 1 ;
- while ((mci_readl(host, SDXC_REG_STAS) & SDXC_FIFOEmpty) &&
- (HAL_TimeBefore(HAL_Ticks(), time)) && host->present);
- if(mci_readl(host, SDXC_REG_STAS) & SDXC_FIFOEmpty){
- SDC_LOGE("read from fifo timeout1\n");
- return;
- }
- buf_temp[j] = mci_readl(host, SDXC_REG_FIFO);
- }
- if((data->sg[i].len) & 0x3) {
- time = HAL_Ticks() + HAL_MSecsToTicks(1000) + 1;
- while ((mci_readl(host, SDXC_REG_STAS) & SDXC_FIFOEmpty) &&
- (HAL_TimeBefore(HAL_Ticks(), time)) && host->present);
- if(mci_readl(host, SDXC_REG_STAS) & SDXC_FIFOEmpty){
- SDC_LOGE("read from fifo timeout2\n");
- return;
- }
- if(((data->sg[i].len) & 0x3) == 2){
- buf_temp[j] = (uint16_t)mci_readl(host, SDXC_REG_FIFO);
- }else if(((data->sg[i].len) & 0x3) == 1){
- buf_temp[j] = (uint8_t)mci_readl(host, SDXC_REG_FIFO);
- }else
- SDC_BUG_ON(1);
- }
- } else if (data->flags & MMC_DATA_WRITE) {
- for (j = 0; j < (data->sg[i].len >> 2); j++) { /* sg[i].len should be multiply of 4 */
- time = HAL_Ticks() + HAL_MSecsToTicks(1000) + 1;
- while ((mci_readl(host, SDXC_REG_STAS) & SDXC_FIFOFull) &&
- (HAL_TimeBefore(HAL_Ticks(), time)) && host->present);
- if(mci_readl(host, SDXC_REG_STAS) & SDXC_FIFOFull){
- SDC_LOGE("write to fifo timeout1\n");
- return;
- }
- mci_writel(buf_temp[j], host, SDXC_REG_FIFO);
- }
- if((data->sg[i].len) & 0x3) {
- time = HAL_Ticks() + HAL_MSecsToTicks(1000) + 1;
- while ((mci_readl(host, SDXC_REG_STAS) & SDXC_FIFOFull) &&
- (HAL_TimeBefore(HAL_Ticks(), time)) && host->present);
- if(mci_readl(host, SDXC_REG_STAS) & SDXC_FIFOFull){
- SDC_LOGE("write to fifo timeout2\n");
- return;
- }
- if(((data->sg[i].len) & 0x3) == 2){
- mci_writel((uint16_t)buf_temp[j], host, SDXC_REG_FIFO);
- }else if(((data->sg[i].len) & 0x3) == 1){
- mci_writel((uint8_t)buf_temp[j], host, SDXC_REG_FIFO);
- }else
- SDC_BUG_ON(1);
- }
- } else {
- SDC_LOGW("illigle data request\n");
- SDC_BUG_ON(1);
- return ;
- }
- }
- HAL_WMB();
- }
- static smc_idma_des *__mci_alloc_idma_des(struct mmc_host *host, struct mmc_data *data)
- {
- smc_idma_des *pdes = host->idma_des;
- uint32_t des_idx = 0;
- uint32_t buff_frag_num = 0;
- uint32_t remain;
- uint32_t i, j;
- uint32_t config;
- /* init IDMA Descriptor, two mode: 1-fixed skip length, 2-chain mode */
- for (i = 0; i < data->sg_len; i++) {
- buff_frag_num = data->sg[i].len >> SDXC_DES_NUM_SHIFT; /* num = len/8192 = len>>13 */
- remain = data->sg[i].len & (SDXC_DES_BUFFER_MAX_LEN - 1);
- if (remain) {
- buff_frag_num++;
- } else {
- remain = SDXC_DES_BUFFER_MAX_LEN;
- }
- for (j = 0; j < buff_frag_num; j++, des_idx++) {
- SDC_Memset((void *)&pdes[des_idx], 0, sizeof(smc_idma_des));
- config = SDXC_IDMAC_DES0_CH | SDXC_IDMAC_DES0_OWN | SDXC_IDMAC_DES0_DIC;
- if (buff_frag_num > 1 && j != buff_frag_num - 1) {
- pdes[des_idx].data_buf1_sz = SDXC_DES_BUFFER_MAX_LEN;
- } else {
- pdes[des_idx].data_buf1_sz = remain;
- }
- pdes[des_idx].buf_addr_ptr1 = SDXC_IDMAC_DES_ADDR((uint32_t)MEMS_VA2PA(HAL_PT_TO_U(data->sg[i].buffer)) + j * SDXC_DES_BUFFER_MAX_LEN);
- if (i == 0 && j == 0) {
- config |= SDXC_IDMAC_DES0_FD;
- }
- if ((i == data->sg_len - 1) && (j == buff_frag_num - 1)) {
- config &= ~SDXC_IDMAC_DES0_DIC;
- config |= SDXC_IDMAC_DES0_LD | SDXC_IDMAC_DES0_ER;
- pdes[des_idx].buf_addr_ptr2 = 0;
- } else {
- pdes[des_idx].buf_addr_ptr2 = SDXC_IDMAC_DES_ADDR((uint32_t)MEMS_VA2PA(HAL_PT_TO_U(&pdes[des_idx + 1])));
- }
- pdes[des_idx].config = config;
- SDC_LOGD("sg %lu, frag %lu, remain %lu, des[%lu](%p): [0]:%lx, [1]:%lx, [2]:%lx, [3]:%lx\n",
- HAL_PR_SZ_L(i), HAL_PR_SZ_L(j), HAL_PR_SZ_L(remain), HAL_PR_SZ_L(des_idx), &pdes[des_idx],
- HAL_PR_SZ_L(((uint32_t *)&pdes[des_idx])[0]), HAL_PR_SZ_L(((uint32_t *)&pdes[des_idx])[1]),
- HAL_PR_SZ_L(((uint32_t *)&pdes[des_idx])[2]), HAL_PR_SZ_L(((uint32_t *)&pdes[des_idx])[3]));
- }
- }
- HAL_FlushDcacheRegion((unsigned long)pdes, HAL_ALIGN(SDXC_MAX_DES_NUM * sizeof(smc_idma_des), OS_CACHE_ALIGN_BYTES));
- HAL_WMB();
- return pdes;
- }
- static smc_idma_des *__mci_prepare_dma(struct mmc_host *host, struct mmc_data *data)
- {
- uint32_t temp;
- smc_idma_des *pdes = NULL;
- /* creat descriptor list, two mode: 1-fixed skip length, 2-chain mode */
- pdes = __mci_alloc_idma_des(host, data);
- if (NULL == pdes) {
- SDC_LOGW("alloc IDMA descriptor failed\n");
- return NULL;
- }
- temp = mci_readl(host, SDXC_REG_GCTRL);
- temp |= SDXC_DMAEnb;
- mci_writel(temp, host, SDXC_REG_GCTRL);
- temp |= (SDXC_DMAReset | SDXC_FIFOReset);
- mci_writel(temp, host, SDXC_REG_GCTRL);
- __mci_check_bit_clear(host, SDXC_REG_GCTRL, (SDXC_DMAReset | SDXC_FIFOReset));
- mci_writel(SDXC_IDMACSoftRST, host, SDXC_REG_DMAC); /* reset IDMAC */
- __mci_check_bit_clear(host, SDXC_REG_DMAC, SDXC_IDMACSoftRST);
- temp = SDXC_IDMACFixBurst | SDXC_IDMACIDMAOn;
- mci_writel(temp, host, SDXC_REG_DMAC);
- /* enable IDMA interrupt, here not use */
- temp = mci_readl(host, SDXC_REG_IDIE);
- temp &= ~(SDXC_IDMACReceiveInt | SDXC_IDMACTransmitInt);
- if (data->flags & MMC_DATA_WRITE) {
- ;//temp |= SDXC_IDMACTransmitInt; /* disable dma int for less irqs */
- } else {
- temp |= SDXC_IDMACReceiveInt;
- }
- mci_writel(temp, host, SDXC_REG_IDIE);
- /* write descriptor address to register */
- mci_writel(SDXC_IDMAC_DES_ADDR((uint32_t)MEMS_VA2PA(HAL_PT_TO_U(pdes))), host, SDXC_REG_DLBA);
- /* write water level */
- mci_writel((BURST_SIZE << 28) | (SMC_RX_WLEVEL << 16) | SMC_TX_WLEVEL,
- host, SDXC_REG_FTRGL);
- return pdes;
- }
- static void __mci_free_idma_des(smc_idma_des *pdes)
- {
- pdes->config &= ~SDXC_IDMAC_DES0_OWN;
- }
- int32_t __mci_wait_access_done(struct mmc_host *host)
- {
- int32_t own_set = 0;
- uint32_t time = HAL_Ticks() + HAL_MSecsToTicks(1000) + 1;
- while (!(mci_readl(host, SDXC_REG_GCTRL) & SDXC_MemAccessDone) && (HAL_TimeBefore(HAL_Ticks(), time)));
- if (!(mci_readl(host, SDXC_REG_GCTRL) & SDXC_MemAccessDone)) {
- SDC_LOGE("wait memory access done timeout !!\n");
- }
- return own_set;
- }
- static int32_t __mci_request_done(struct mmc_host *host)
- {
- struct mmc_request *mrq = host->mrq;
- unsigned long iflags;
- uint32_t temp;
- int32_t ret = 0;
- iflags = HAL_EnterCriticalSection();
- if (host->wait != SDC_WAIT_FINALIZE) {
- HAL_ExitCriticalSection(iflags);
- SDC_LOGW("%s nothing finalize, wt %lx\n", __func__, HAL_PR_SZ_L(host->wait));
- return -1;
- }
- host->wait = SDC_WAIT_NONE;
- host->trans_done = 0;
- host->dma_done = 0;
- HAL_ExitCriticalSection(iflags);
- if (host->int_sum & SDXC_IntErrBit) {
- SDC_LOGE("SDC err, cmd %ld, %s%s%s%s%s%s%s%s%s%s\n",
- HAL_PR_SZ_L(host->smc_cmd & SDXC_CMD_OPCODE),
- host->int_sum & SDXC_RespErr ? " RE" : "",
- host->int_sum & SDXC_RespCRCErr ? " RCE" : "",
- host->int_sum & SDXC_DataCRCErr ? " DCE" : "",
- host->int_sum & SDXC_RespTimeout ? " RTO" : "",
- host->int_sum & SDXC_DataTimeout ? " DTO" : "",
- host->int_sum & SDXC_DataStarve ? " DS" : "",
- host->int_sum & SDXC_FIFORunErr ? " FRE" : "",
- host->int_sum & SDXC_HardWLocked ? " HL" : "",
- host->int_sum & SDXC_StartBitErr ? " SBE" : "",
- host->int_sum & SDXC_EndBitErr ? " EBE" : "");
- sdc_hex_dump_word((void *)(SDC_GPIO_BASE+0xB0),0xff);
- if (host->sdc_id == 0) {
- sdc_hex_dump_word((void *)SDC_CCM_SDC0_SCLK_CTRL ,0x200);
- sdc_hex_dump_word((void *)SMC0_BASE ,0x200);
- } else if (host->sdc_id == 1) {
- sdc_hex_dump_word((void *)SDC_CCM_SDC1_SCLK_CTRL ,0x200);
- sdc_hex_dump_word((void *)SMC1_BASE ,0x200);
- }
- ret = -1;
- goto out;
- }
- if (mrq->cmd->flags & MMC_RSP_136) {
- mrq->cmd->resp[0] = mci_readl(host, SDXC_REG_RESP3);
- mrq->cmd->resp[1] = mci_readl(host, SDXC_REG_RESP2);
- mrq->cmd->resp[2] = mci_readl(host, SDXC_REG_RESP1);
- mrq->cmd->resp[3] = mci_readl(host, SDXC_REG_RESP0);
- } else
- mrq->cmd->resp[0] = mci_readl(host, SDXC_REG_RESP0);
- out:
- if (mrq->data) {
- if (host->dma_hdle) {
- __mci_wait_access_done(host);
- mci_writel(0x337, host, SDXC_REG_IDST); /* clear interrupt flags */
- mci_writel(0, host, SDXC_REG_IDIE); /* disable idma interrupt */
- mci_writel(0, host, SDXC_REG_DMAC); /* idma off */
- temp = mci_readl(host, SDXC_REG_GCTRL);
- mci_writel(temp | SDXC_DMAReset, host, SDXC_REG_GCTRL);
- temp &= ~SDXC_DMAEnb;
- mci_writel(temp, host, SDXC_REG_GCTRL); /* disable IDMA */
- temp |= SDXC_FIFOReset;
- mci_writel(temp, host, SDXC_REG_GCTRL);
- __mci_free_idma_des((void *)host->dma_hdle);
- host->dma_hdle = NULL;
- }
- mci_writel(mci_readl(host, SDXC_REG_GCTRL) | SDXC_FIFOReset,
- host, SDXC_REG_GCTRL);
- }
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode == CARD_DETECT_BY_D3){
- mci_writel((SDXC_CardInsert|SDXC_CardRemove)|host->sdio_irq_mask, host, SDXC_REG_IMASK);
- } else
- #endif
- {
- mci_writel(host->sdio_irq_mask, host, SDXC_REG_IMASK);
- }
- if (host->int_sum & (SDXC_RespErr | SDXC_HardWLocked | SDXC_RespTimeout)) {
- SDC_LOGE("sdc %d abnormal status: %s\n", __LINE__,
- host->int_sum & SDXC_HardWLocked ? "HardWLocked" : "RespErr");
- }
- mci_writel(0xffff, host, SDXC_REG_RINTR);
- SDC_LOGD("SDC done, resp %lx %lx %lx %lx\n", HAL_PR_SZ_L(mrq->cmd->resp[0]),
- HAL_PR_SZ_L(mrq->cmd->resp[1]), HAL_PR_SZ_L(mrq->cmd->resp[2]), HAL_PR_SZ_L(mrq->cmd->resp[3]));
- if (mrq->data && (host->int_sum & SDXC_IntErrBit)) {
- SDC_LOGW("found data error, need to send stop command !!\n");
- __mci_reset(host);
- __mci_program_clk(host);
- }
- host->int_err = 0;
- return ret;
- }
- #define mci_writel_irq(value, host, reg) \
- ({ uint32_t val;\
- printf("+irq reg add 0x%x write val 0x%x\n", (uint32_t)(host)->reg_base + reg, value);\
- writel((value), (uint32_t)(host)->reg_base + reg);\
- val = readl((uint32_t)(host)->reg_base + reg);\
- printf("%s,%d\n", __FUNCTION__, __LINE__);\
- printf("-irq reg read val 0x%x\n", (unsigned int)val);})
- //#ifdef CONFIG_SDIO_IRQ_SUPPORT
- __nonxip_text
- static void __mci_enable_sdio_irq(struct mmc_host *host, int enable)
- {
- uint32_t imask;
- uint32_t flags = HAL_EnterCriticalSection();
- imask = mci_readl(host, SDXC_REG_IMASK);
- if (enable){
- // mci_writel(SDXC_SDIOInt, host, SDXC_REG_RINTR);
- host->sdio_irq_mask = SDXC_SDIOInt;
- imask |= SDXC_SDIOInt;
- }else{
- host->sdio_irq_mask = 0;
- imask &= ~SDXC_SDIOInt;
- }
- mci_writel(imask, host, SDXC_REG_IMASK);
- HAL_ExitCriticalSection(flags);
- }
- __nonxip_text
- static inline void __mci_signal_sdio_irq(struct mmc_host *host)
- {
- // if (!host->card || !host->card->irq_handler) {
- if (!host->card) {
- SDC_IT_LOGE("BUG at __mci_signal_sdio_irq():%d\n", __LINE__);
- return;
- }
- #ifdef SD_PERF_TRACE_ON
- host->start_sdio_irq_times_ns = HAL_GetTimeNs();
- host->sdio_irq_count ++;
- #endif
- __mci_enable_sdio_irq(host, 0);
- host->sdio_irq_pending = true;
- //if (host.sdio_irq_thread)
- //xTaskResumeFromISR(host->sdio_irq_thread.handle);
- OS_SemaphoreRelease(&host->sdio_irq_signal);
- }
- void rom_HAL_SDC_Enable_Sdio_Irq(struct mmc_host *host, int enable)
- {
- uint32_t flags = 0;
- __mci_enable_sdio_irq(host,enable);
- }
- //#endif
- static void __mci_clk_prepare_enable(struct mmc_host *host)
- {
- if (host->sdc_id == 0) {
- SDC0_CCM_BusEnableClock(); /* clock enable */
- SDC0_CCM_BusReleaseRest(); /* reset and gating */
- SDC0_CCM_EnableMClock();
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- SDC1_CCM_BusEnableClock(); /* clock enable */
- SDC1_CCM_BusReleaseRest(); /* reset and gating */
- SDC1_CCM_EnableMClock();
- #endif
- }
- }
- static void __mci_clk_disable_unprepare(struct mmc_host *host)
- {
- if (host->sdc_id == 0) {
- SDC0_CCM_BusDisableClock();
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- SDC1_CCM_BusDisableClock();
- #endif
- }
- }
- static void __mci_hold_io(struct mmc_host* host)
- {
- #ifdef __CONFIG_ARCH_APP_CORE
- #ifndef NUSE_STANDARD_INTERFACE
- /* disable gpio to avoid power leakage */
- if (host->pin_ref) {
- HAL_BoardIoctl(HAL_BIR_PINMUX_DEINIT, HAL_MKDEV(HAL_DEV_MAJOR_SDC,
- host->sdc_id), SDCGPIO_BAS);
- host->pin_ref = 0;
- }
- #else
- SDC_LOGN("Not implement %s,%d\n", __FUNCTION__, __LINE__);
- #endif
- #endif
- }
- static void __mci_restore_io(struct mmc_host* host)
- {
- #ifdef __CONFIG_ARCH_APP_CORE
- #ifndef NUSE_STANDARD_INTERFACE
- if (host->pin_ref == 0) {
- HAL_BoardIoctl(HAL_BIR_PINMUX_INIT, HAL_MKDEV(HAL_DEV_MAJOR_SDC,
- host->sdc_id), SDCGPIO_BAS);
- host->pin_ref = 1;
- }
- #else
- SDC_LOGN("Not implement %s,%d\n", __FUNCTION__, __LINE__);
- #endif
- #
- #endif
- }
- __nonxip_text
- static irqreturn_t __mci_irq_handler(uint32_t sdc_id)
- {
- struct mmc_host *host = _mci_host[sdc_id];
- uint32_t sdio_int = 0;
- uint32_t raw_int;
- uint32_t msk_int;
- uint32_t idma_inte;
- uint32_t idma_int;
- #if (defined(__CONFIG_SECTION_ATTRIBUTE_NONXIP) && SDC_DEBUG)
- __nonxip_rodata static const char __s_func[] = "__mci_irq_handler";
- #endif
- //SDC_IT_LOGD("***%s,%d***\n",__FUNCTION__, __LINE__);
- if (!host) {
- SDC_IT_LOGE_RAW(ROM_ERR_MASK, "%s,%d no host exist!\n", __func__, __LINE__);
- return IRQ_NONE;
- }
- if (!host->present) {
- if (host->sdc_id == 0) {
- SDC0_CCM_BusEnableClock();
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- SDC1_CCM_BusEnableClock();
- #endif
- }
- }
- idma_int = mci_readl(host, SDXC_REG_IDST);
- idma_inte = mci_readl(host, SDXC_REG_IDIE);
- raw_int = mci_readl(host, SDXC_REG_RINTR);
- msk_int = mci_readl(host, SDXC_REG_MISTA);
- if (!msk_int && !idma_int) {
- SDC_IT_LOGE("sdc nop irq: ri:%08lx mi:%08lx ie:%08lx idi:%08lx\n",
- HAL_PR_SZ_L(raw_int), HAL_PR_SZ_L(msk_int), HAL_PR_SZ_L(idma_inte), HAL_PR_SZ_L(idma_int));
- return IRQ_NONE;
- }
- host->int_sum = raw_int;
- SDC_IT_LOGD("sdc %d ri:%02x(%02x), mi:%x, ie:%x, idi:%x\n", __LINE__,
- (int)raw_int, (int)host->int_sum,
- (int)msk_int, (int)idma_inte, (int)idma_int);
- (void)idma_inte;
- #ifdef CONFIG_SDIO_IRQ_SUPPORT
- if (msk_int & SDXC_SDIOInt) {
- sdio_int = 1;
- mci_writel(SDXC_SDIOInt, host, SDXC_REG_RINTR);
- goto sdio_out;
- }
- #endif
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode == CARD_DETECT_BY_D3) {
- if (msk_int & SDXC_CardInsert) {
- SDC_IT_LOGN("Card Insert !!\n");
- host->present = 1;
- SDC_IT_ModTimer(&host->cd_timer, 10);
- } else if (msk_int & SDXC_CardRemove) {
- SDC_IT_LOGN("Card Remove !!\n");
- host->present = 0;
- SDC_IT_ModTimer(&host->cd_timer, 10);
- }
- }
- #endif
- if (host->wait == SDC_WAIT_NONE && !sdio_int) {
- SDC_IT_LOGE("%s nothing to complete, ri:%08lx, mi:%08lx\n",
- __s_func, HAL_PR_SZ_L(raw_int), HAL_PR_SZ_L(msk_int));
- goto irq_out;
- }
- if ((raw_int & SDXC_IntErrBit) || (idma_int & SDXC_IDMA_ERR)) {
- host->int_err = raw_int & SDXC_IntErrBit;
- host->wait = SDC_WAIT_FINALIZE;
- SDC_IT_LOGE("%s,%d raw_int:%lx err!\n", __s_func, __LINE__, HAL_PR_SZ_L(raw_int));
- goto irq_out;
- }
- if (raw_int & SDXC_HardWLocked) {
- SDC_IT_LOGE("command hardware lock\n");
- }
- if (idma_int & (SDXC_IDMACTransmitInt|SDXC_IDMACReceiveInt)) {
- host->dma_done = 1;
- mci_writel(idma_int, host, SDXC_REG_IDST);
- }
- if (msk_int & (SDXC_AutoCMDDone|SDXC_DataOver|SDXC_CmdDone|SDXC_VolChgDone))
- host->trans_done = 1;
- if ((host->trans_done && \
- (host->wait == SDC_WAIT_AUTOCMD_DONE || host->wait == SDC_WAIT_DATA_OVER
- || host->wait == SDC_WAIT_CMD_DONE || host->wait == SDC_WAIT_SWITCH1V8))
- || (host->trans_done && host->dma_done && (host->wait & SDC_WAIT_IDMA_DONE))) {
- host->wait = SDC_WAIT_FINALIZE;
- }
- irq_out:
- mci_writel(msk_int & (~SDXC_SDIOInt), host, SDXC_REG_RINTR);
- if (host->wait == SDC_WAIT_FINALIZE) {
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode == CARD_DETECT_BY_D3){
- mci_writel(SDXC_CardInsert|SDXC_CardRemove|host->sdio_irq_mask,
- host, SDXC_REG_IMASK);
- } else
- #endif
- {
- mci_writel(host->sdio_irq_mask, host, SDXC_REG_IMASK);
- }
- HAL_WMB();
- if(!OS_IsISRContext()){
- SDC_BUG_ON(1);
- sys_abort();
- }
- SDC_SemPost(&host->lock);
- SDC_IT_LOGD("SDC irq post, trans:%d, dma:%d\n",
- (int)host->trans_done, (int)host->dma_done);
- }
- #ifdef CONFIG_SDIO_IRQ_SUPPORT
- sdio_out:
- if (sdio_int)
- __mci_signal_sdio_irq(host);
- #endif
- return IRQ_HANDLED;
- }
- __nonxip_text
- irqreturn_t SDC0_IRQHandler(int id, void *data)
- {
- return __mci_irq_handler(SDC0);
- }
- #if SDC1_SUPPORT
- __nonxip_text
- irqreturn_t SDC1_IRQHandler(int id, void *data) //static
- {
- return __mci_irq_handler(SDC1);
- }
- #endif
- /* clock config:
- * SYS_CRYSTAL: 26M
- * 400K, SCLK-26M, 26M/(2^3)/(7+1)/2 = 361K
- * SYS_CRYSTAL: 24M
- * 400K, SCLK-24M, 24M/(2^2)/(7+1)/2 = 375K
- *
- * 25M, SCLK-192M, 192M/(2^0)/(3+1)/2 = 24M
- * 50M, SCLK-192M, 192M/(2^0)/(1+1)/2 = 48M
- * 64M, SCLK-192M, 192M/(2^0)/(1+1)/2 = 48M
- */
- #define DEFINE_SYS_CRYSTAL HAL_GetHFClock()
- #define DEFINE_SYS_DEVCLK HAL_GetDevClock()
- static int32_t __mci_update_clock(struct mmc_host *host, uint32_t cclk)
- {
- uint32_t sclk;
- uint32_t div;
- uint32_t rval;
- uint32_t src = 0;
- uint32_t m, n;
- if (cclk > DEFINE_SYS_CRYSTAL/2) {
- #ifdef NUSE_STANDARD_INTERFACE
- src = 1;
- #else
- src = CCM_AHB_PERIPH_CLK_SRC_DEVCLK;
- #endif
- sclk = DEFINE_SYS_DEVCLK;
- } else {
- #ifdef NUSE_STANDARD_INTERFACE
- src = 0;
- #else
- src = CCM_AHB_PERIPH_CLK_SRC_HFCLK;
- #endif
- sclk = DEFINE_SYS_CRYSTAL;
- }
- cclk = cclk * 2; /* 2x MODE clock configure */
- div = (2 * sclk + cclk) / (2 * cclk);
- div = div == 0 ? 1 : div;
- if (div > 128) {
- n = 3;
- m = 16;
- SDC_LOGE("source clk is too high!\n");
- } else if (div > 64) {
- n = 3;
- m = div >> 3;
- } else if (div > 32) {
- n = 2;
- m = div >> 2;
- } else if (div > 16) {
- n = 1;
- m = div >> 1;
- } else {
- n = 0;
- m = div;
- }
- m = m - 1;
- #ifdef NUSE_STANDARD_INTERFACE
- /*
- if (src) {
- rval |= (2U << 20) | (1 << 8);
- SDC_LOGN("%s,%d check spec. bit20, 8!!\n", __func__, __LINE__);
- }
- */
- if (host->sdc_id == 0) {
- rval = readl(SDC_CCM_SDC0_SCLK_CTRL);
- rval &= ~(1U<<31);
- writel(rval,SDC_CCM_SDC0_SCLK_CTRL);
- HAL_WMB();
- rval = (src << 24) | (n << 8) | (m);
- writel(rval,SDC_CCM_SDC0_SCLK_CTRL);
- HAL_WMB();
- rval = readl(SDC_CCM_SDC0_SCLK_CTRL);
- rval |= (1U<<31);
- writel(rval,SDC_CCM_SDC0_SCLK_CTRL);
- HAL_WMB();
- SDC_LOGN("SDC clock=%ld kHz,src:%x, n:%d, m:%d\n",
- HAL_PR_SZ_L((src ? DEFINE_SYS_DEVCLK:DEFINE_SYS_CRYSTAL)/(1<<n)/(m+1)/2),
- (int)src, (int)n, (int)m);
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- rval = readl(SDC_CCM_SDC1_SCLK_CTRL);
- rval &= ~(1U<<31);
- writel(rval,SDC_CCM_SDC1_SCLK_CTRL);
- HAL_WMB();
- rval = (src << 24) | (n << 8) | (m);
- writel(rval,SDC_CCM_SDC1_SCLK_CTRL);
- HAL_WMB();
- rval = readl(SDC_CCM_SDC1_SCLK_CTRL);
- rval |= (1U<<31);
- writel(rval,SDC_CCM_SDC1_SCLK_CTRL);
- HAL_WMB();
- SDC_LOGN("SDC clock=%ld kHz,src:%x, n:%d, m:%d\n",
- HAL_PR_SZ_L((src?DEFINE_SYS_DEVCLK:DEFINE_SYS_CRYSTAL)/(1<<n)/(m+1)/2),
- (int)src, (int)n, (int)m);
- #endif
- }
- #else
- if (host->sdc_id == 0) {
- SDC0_DisableMClock();
- SDC0_SetMClock(src, n << CCM_PERIPH_CLK_DIV_N_SHIFT, m << CCM_PERIPH_CLK_DIV_M_SHIFT);
- SDC0_CCM_EnableMClock();
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- SDC1_DisableMClock();
- SDC1_SetMClock(src, n << CCM_PERIPH_CLK_DIV_N_SHIFT, m << CCM_PERIPH_CLK_DIV_M_SHIFT);
- SDC1_CCM_EnableMClock();
- #endif
- }
- SDC_LOGN("SDC source:%u MHz clock=%u kHz, src:%x, n:%d, m:%d\n", sclk/1000000,
- sclk/(1<<n)/(m+1)/2000, (int)src, (int)n, (int)m);
- #endif
- /* clear internal divider */
- rval = mci_readl(host, SDXC_REG_CLKCR) & (~0xff);
- mci_writel(rval, host, SDXC_REG_CLKCR);
- sdc_hex_dump_word((void *)SDC_CCM_BASE ,0x900);
- return cclk;
- }
- int32_t rom_HAL_SDC_Update_Clk(struct mmc_host *host, uint32_t clk)
- {
- uint32_t rval;
- if (!host || clk < 200000) { /* 200K */
- SDC_LOGE_RAW(ROM_ERR_MASK, "%s,%d err", __func__, __LINE__);
- return -1;
- }
- /* Disable Clock */
- rval = mci_readl(host, SDXC_REG_CLKCR) & (~SDXC_CardClkOn) & (~SDXC_LowPowerOn);
- mci_writel(rval, host, SDXC_REG_CLKCR);
- if (__mci_program_clk(host)) {
- SDC_LOGE("Clock Program Failed 0!!\n");
- return -1;
- }
- __mci_update_clock(host, clk);
- /* Re-enable Clock */
- rval = mci_readl(host, SDXC_REG_CLKCR) | (SDXC_CardClkOn);// | SDXC_LowPowerOn;
- mci_writel(rval, host, SDXC_REG_CLKCR);
- if (__mci_program_clk(host)) {
- SDC_LOGE("Clock Program Failed 1!!\n");
- return -1;
- }
- host->clk = clk;
- return 0;
- }
- static int32_t __mci_update_clk(struct mmc_host *host)
- {
- uint32_t rval;
- int32_t ret = 0;
- uint32_t time = HAL_Ticks() + HAL_MSecsToTicks(1000) + 1;
- mci_writel(mci_readl(host, SDXC_REG_CLKCR) | SDXC_Mask_Data0,\
- host, SDXC_REG_CLKCR);
- rval = SDXC_Start|SDXC_UPCLKOnly|SDXC_WaitPreOver;
- #ifdef CONFIG_SDC_SUPPORT_1V8
- if (host->voltage_switching)
- rval |= SDXC_VolSwitch;
- #endif
- mci_writel(rval, host, SDXC_REG_CMDR);
- do {
- rval = mci_readl(host, SDXC_REG_CMDR);
- } while ((rval & SDXC_Start) && HAL_TimeBefore(HAL_Ticks(), time));
- if (mci_readl(host, SDXC_REG_CMDR) & SDXC_Start) {
- SDC_LOGE("sdc update clock timeout, fatal error!!!\n");
- __mci_force_dump_host_info(host);
- ret = -1;
- }
- if (!ret)
- SDC_LOGD("sdc update clock ok\n");
- /* clear command done flag */
- rval = mci_readl(host, SDXC_REG_RINTR);
- mci_writel(rval, host, SDXC_REG_RINTR);
- mci_writel(mci_readl(host, SDXC_REG_CLKCR) & ~SDXC_Mask_Data0,\
- host, SDXC_REG_CLKCR);
- return ret;
- }
- int32_t rom_HAL_SDC_Clk_PWR_Opt(struct mmc_host *host, uint32_t oclk_en, uint32_t pwr_save)
- {
- uint32_t rval;
- if (!host->power_on)
- return 0;
- rval = mci_readl(host, SDXC_REG_CLKCR);
- rval &= ~(SDXC_CardClkOn | SDXC_LowPowerOn);
- if (oclk_en)
- rval |= SDXC_CardClkOn;
- if (pwr_save)
- rval |= SDXC_LowPowerOn;
- mci_writel(rval, host, SDXC_REG_CLKCR);
- __mci_update_clk(host);
- return 0;
- }
- static void __mci_debounce_onoff(struct mmc_host *host, uint32_t onoff)
- {
- uint32_t rval = mci_readl(host, SDXC_REG_GCTRL);
- rval &= ~SDXC_DebounceEnb;
- if (onoff)
- rval |= SDXC_DebounceEnb;
- mci_writel(rval, host, SDXC_REG_GCTRL);
- SDC_LOGD("%s,%d,%ld\n",__FUNCTION__,__LINE__, HAL_PR_SZ_L(onoff));
- }
- uint32_t HAL_SDC_Is_Busy(struct mmc_host *host)
- {
- return mci_readl(host, SDXC_REG_STAS) & SDXC_CardBusy;
- }
- static int32_t __mci_check_busy_over(struct mmc_host *host)
- {
- uint32_t i;
- for(i = 0; i< SDC_BUSY_WAIT_LOOP; i++){
- if(!(mci_readl(host, SDXC_REG_STAS) & SDXC_CardBusy)){
- return 0;
- }
- if(i>(SDC_BUSY_WAIT_LOOP/8)) {
- mmc_mdelay(10);
- if(i%8)
- SDC_LOGW("Waiting reg %x bitmap %x clear v %x,i %x\n",\
- HAL_PR_SZ(HAL_PT_TO_U(host->reg_base)) + SDXC_REG_STAS,\
- (unsigned int)SDXC_CardBusy,\
- (unsigned int)mci_readl(host, SDXC_CardBusy),\
- (unsigned int)i);
- }
- SDC_LOGD("Waiting reg %x bitmap %x clear v %x,i %x\n",\
- HAL_PR_SZ(HAL_PT_TO_U(host->reg_base)) + SDXC_REG_STAS,\
- (unsigned int)SDXC_CardBusy,\
- (unsigned int)mci_readl(host, SDXC_CardBusy),\
- (unsigned int)i);
- }
- SDC_LOGE("Wait busy timeout %x,%x\n",
- (unsigned int)mci_readl(host, SDXC_REG_STAS), (unsigned int)i);
- return -1;
- }
- int32_t __mci_check_bit_clear(struct mmc_host *host, uint32_t reg_offset, uint32_t bit_map)
- {
- uint32_t i;
- for(i = 0; i< SDC_BUSY_WAIT_LOOP; i++){
- if(!(mci_readl(host, reg_offset) & bit_map)){
- SDC_LOGD("Wait reg %p bitmap %x clear v %lx,i %x ok\n",\
- (host->reg_base) + reg_offset,\
- (unsigned int)bit_map,\
- HAL_PR_SZ_L(mci_readl(host, reg_offset)),\
- (unsigned int)i);
- return 0;
- }
- if(i>(SDC_BUSY_WAIT_LOOP/8)) {
- mmc_mdelay(10);
- if(i%8)
- SDC_LOGW("Waiting reg %p bitmap %x clear v %lx,i %x\n",\
- (host->reg_base) + reg_offset,\
- (unsigned int)bit_map,\
- HAL_PR_SZ_L(mci_readl(host, reg_offset)),\
- (unsigned int)i);
- }
- }
- SDC_LOGE("Wait reg %p bitmap %x clear timeout v %lx,i %x\n",\
- (host->reg_base) + reg_offset,\
- (unsigned int) bit_map,\
- HAL_PR_SZ_L(mci_readl(host, reg_offset)),\
- (unsigned int)i);
- return -1;
- }
- void HAL_SDC_Set_BusWidth(struct mmc_host *host, uint32_t width)
- {
- if (!host) {
- SDC_LOGE_RAW(ROM_ERR_MASK, "%s,%d err", __func__, __LINE__);
- return ;
- }
- switch (width) {
- case MMC_BUS_WIDTH_1:
- mci_writel(SDXC_WIDTH1, host, SDXC_REG_WIDTH);
- break;
- case MMC_BUS_WIDTH_4:
- mci_writel(SDXC_WIDTH4, host, SDXC_REG_WIDTH);
- break;
- #ifdef CONFIG_USE_MMC
- case MMC_BUS_WIDTH_8:
- mci_writel(SDXC_WIDTH8, host, SDXC_REG_WIDTH);
- break;
- #endif
- default:
- SDC_BUG_ON(1);
- return ;
- }
- host->buswidth = width;
- }
- static void __mci_send_cmd(struct mmc_host *host, struct mmc_command *cmd)
- {
- uint32_t imask = SDXC_IntErrBit;
- uint32_t cmd_val = SDXC_Start | (cmd->opcode & 0x3f);
- unsigned long iflags;
- uint32_t wait = SDC_WAIT_CMD_DONE;
- struct mmc_data *data = cmd->data;
- if (cmd->opcode == MMC_GO_IDLE_STATE) {
- cmd_val |= SDXC_SendInitSeq;
- imask |= SDXC_CmdDone;
- }
- #ifdef CONFIG_SDC_SUPPORT_1V8
- if (cmd->opcode == SD_SWITCH_VOLTAGE) {
- cmd_val |= SDXC_VolSwitch;
- imask |= SDXC_VolChgDone;
- host->voltage_switching = 1;
- wait = SDC_WAIT_SWITCH1V8;
- /* switch controller to high power mode */
- HAL_SDC_Clk_PWR_Opt(host, 1, 0);
- }
- #endif
- if (cmd->flags & MMC_RSP_PRESENT) { /* with response */
- cmd_val |= SDXC_RspExp;
- if (cmd->flags & MMC_RSP_136) /* long response */
- cmd_val |= SDXC_LongRsp;
- if (cmd->flags & MMC_RSP_CRC)
- cmd_val |= SDXC_CheckRspCRC;
- if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) { /* with data */
- if (!data) {
- SDC_LOGE("%s,%d no data exist!\n", __func__, __LINE__);
- return ;
- }
- cmd_val |= SDXC_DataExp | SDXC_WaitPreOver;
- wait = SDC_WAIT_DATA_OVER;
- if (data->flags & MMC_DATA_STREAM) { /* sequence mode */
- imask |= SDXC_AutoCMDDone;
- cmd_val |= SDXC_Seqmod | SDXC_SendAutoStop;
- wait = SDC_WAIT_AUTOCMD_DONE;
- }
- if (cmd->stop) {
- imask |= SDXC_AutoCMDDone;
- cmd_val |= SDXC_SendAutoStop;
- wait = SDC_WAIT_AUTOCMD_DONE;
- } else
- imask |= SDXC_DataOver;
- if (data->flags & MMC_DATA_WRITE) {
- cmd_val |= SDXC_Write;
- } else if (host->dma_hdle) {
- wait |= SDC_WAIT_IDMA_DONE;
- }
- SDC_LOGD("blk_size:%lu, sg len:%lu\n",HAL_PR_SZ_L(data->blksz), HAL_PR_SZ_L(data->sg->len));
- } else
- imask |= SDXC_CmdDone;
- } else
- imask |= SDXC_CmdDone;
- SDC_LOGD("sdc cmd:%ld(%lx), arg:%lx ie:%lx wt:%lx len:%lu\n",
- HAL_PR_SZ_L(cmd_val & SDXC_CMD_OPCODE), HAL_PR_SZ_L(cmd_val), HAL_PR_SZ_L(cmd->arg), HAL_PR_SZ_L(imask), HAL_PR_SZ_L(wait),
- HAL_PR_SZ_L(cmd->data ? cmd->data->blksz * cmd->data->blocks : 0));
- iflags = HAL_EnterCriticalSection();
- host->smc_cmd = cmd_val;
- host->wait = wait;
- mci_writel(imask | host->sdio_irq_mask, host, SDXC_REG_IMASK);
- if (cmd_val & SDXC_SendAutoStop)
- mci_writel(0, host, SDXC_REG_A12A);
- else
- mci_writel(0xffff, host, SDXC_REG_A12A);
- mci_writel(cmd->arg, host, SDXC_REG_CARG);
- HAL_WMB();
- mci_writel(cmd_val, host, SDXC_REG_CMDR);
- HAL_ExitCriticalSection(iflags);
- if (data && NULL == host->dma_hdle) {
- __mci_trans_by_ahb(host, data);
- }
- }
- #ifdef SD_PERF_TRACE_ON
- static void __mci_start_data_time_stats(struct mmc_host *host, struct mmc_request *mrq)
- {
- if((mrq->data) && (mmc_cmd_type(mrq->cmd) == MMC_CMD_ADTC)){
- if( (mrq->data->blksz * mrq->data->blocks) > 4 )
- host->start_times_us = HAL_GetTimeUs();
- }
- }
- /*this func can not be called by irq_server_function;
- *because there are using printf(only printf support u64).
- *if you want to use it in irq_server_funciton,printf to printk
- * */
- static void __mci_end_data_time_stats(struct mmc_host *host, struct mmc_request *mrq)
- {
- if((mrq->data) && (mmc_cmd_type(mrq->cmd) == MMC_CMD_ADTC) \
- && ((mrq->data->blksz * mrq->data->blocks) > 4)){
- uint64_t time_use_us = (uint64_t)HAL_GetTimeUs() - host->start_times_us;
- if((mrq->data->flags) & MMC_DATA_WRITE ) {
- host->wbytes += mrq->data->blksz * mrq->data->blocks ;
- host->wtimes_us += time_use_us;
- host->wcount ++;
- if(host->wcount && !(host->wcount % SD_PERF_TRACE_COUNT)) {
- printf("Stats Total write:bytes %lld, time us %lu, count %lld, %lld KB\n",\
- host->wbytes, host->wtimes_us, host->wcount,\
- __mci_get_rate(host->wbytes, host->wtimes_us)/1024);
- //host->wtimes_us = 0;
- //host->wbytes = 0;
- //host->wcount = 0;
- }
- } else if((mrq->data->flags) & MMC_DATA_READ) {
- host->rbytes += mrq->data->blksz * mrq->data->blocks;
- host->rtimes_us += time_use_us;
- host->rcount++;
- if( host->rcount &&!(host->rcount % SD_PERF_TRACE_COUNT)) {
- printf("Stats Total read: byte %lld, time us %lu, count %lld, %lldKB\n",\
- host->rbytes, host->rtimes_us, host->rcount,\
- __mci_get_rate(host->rbytes, host->rtimes_us)/1024);
- //host->rtimes_us = 0;
- //host->rbytes = 0;
- //host->rcount = 0;
- }
- }
- }
- }
- #endif
- int32_t do_rom_HAL_SDC_Request(struct mmc_host *host, struct mmc_request *mrq)
- {
- int32_t ret = 0;
- struct mmc_command *cmd = mrq->cmd;
- struct mmc_data *data = mrq->data;
- #ifdef CONFIG_SDC_DMA_USED
- uint32_t sdc_use_dma = host->dma_use;
- #else
- uint32_t sdc_use_dma = 0;
- #endif
- if (!host->present) {
- SDC_LOGW("sdc:%p no medium present\n", host);
- SDC_SemRest((&host->lock));
- return -1;
- }
- #ifdef CONFIG_SD_PM
- if (host->suspend) {
- SDC_LOGE("sdc:%p has suspended!\n", host);
- return -1;
- }
- #endif
- #ifdef SD_PERF_TRACE_ON
- __mci_start_data_time_stats(host, mrq);
- #endif
- __mci_check_busy_over(host);
- __mci_check_bit_clear(host, SDXC_REG_GCTRL, SDXC_HWReset);
- SDC_MutexLock(&host->thread_lock, SDC_THREAD_TIMEOUT);
- /* disable debounce */
- __mci_debounce_onoff(host, 0);
- host->mrq = mrq;
- if (data) {
- uint32_t i;
- uint32_t byte_cnt = 0;
- struct scatterlist *sg = data->sg;
- uint32_t sg_len = data->sg_len;
- unsigned long addr = 0;
- uint32_t len = 0;
- for (i = 0; i < sg_len; i++) {
- addr = HAL_PT_TO_U(sg[i].buffer);
- len = sg[i].len;
- byte_cnt += sg[i].len;
- #ifdef CONFIG_SDC_DMA_USED
- if ((addr & 0x03)) {
- sdc_use_dma = 0;
- SDC_LOGW("unalign addr %lx, len %ld wr %lx\n", HAL_PR_SZ_L(addr), HAL_PR_SZ_L(len), HAL_PR_SZ_L(data->flags & MMC_DATA_WRITE));
- continue;
- }
- if((addr & (OS_CACHE_ALIGN_BYTES - 1))\
- || (len & (OS_CACHE_ALIGN_BYTES - 1))) {
- SDC_LOGD("unalign addr %lx, len %ld wr %lx\n", HAL_PR_SZ_L(addr), HAL_PR_SZ_L(len), HAL_PR_SZ_L(data->flags & MMC_DATA_WRITE));
- }
- HAL_FlushDcacheRegion((unsigned long)sg[i].buffer, HAL_ALIGN(sg[i].len, OS_CACHE_ALIGN_BYTES));
- #endif
- }
- #ifdef CONFIG_SDC_DMA_USED
- if (byte_cnt <= SDC_MAX_CPU_TRANS_LEN) {
- sdc_use_dma = 0;
- }
- #endif
- if (byte_cnt != (data->blksz * data->blocks)) {
- SDC_LOGE("sg data len %ld not equel data's len %ld\n", HAL_PR_SZ_L(byte_cnt), HAL_PR_SZ_L(data->blksz * data->blocks));
- }
- mci_writel(data->blksz, host, SDXC_REG_BLKSZ);
- mci_writel(byte_cnt, host, SDXC_REG_BCNTR);
- if (sdc_use_dma && byte_cnt > SDC_MAX_CPU_TRANS_LEN) { /* transfer by idma */
- __mci_sel_access_mode(host, SDXC_ACCESS_BY_DMA);
- host->dma_hdle = __mci_prepare_dma(host, data);
- if (NULL == host->dma_hdle) {
- SDC_LOGW("SDC prepare DMA failed\n");
- __mci_sel_access_mode(host, SDXC_ACCESS_BY_AHB);
- }
- } else {
- /* switch data bus to ahb */
- __mci_sel_access_mode(host, SDXC_ACCESS_BY_AHB);
- }
- }
- __mci_send_cmd(host, cmd);
- #if defined(CONFIG_SOC_SUN20IW1) && defined(CONFIG_OS_MELIS)
- struct timespec64 time0 ={0}, time1={0};
- do_gettimeofday(&time0);
- ret = SDC_SemPend(&host->lock, SDC_DMA_TIMEOUT);
- do_gettimeofday(&time1);
- if ((ret != HAL_OK && host->present) && \
- (((time1.tv_sec*1000+time1.tv_nsec/1000000) - (time0.tv_sec*1000+time0.tv_nsec/1000000)) < SDC_DMA_TIMEOUT))
- {
- //增加这里的原因是防止读写sdmmc的task被esKRNL_TimeDlyResume,出现这种情况,会导致信号量提前退出
- //如果是正常的timeout则不会跑到这里面
- SDC_LOGE("===SDC_SemPend abnormal===\n");
- ret = SDC_SemPend(&host->lock, SDC_DMA_TIMEOUT);
- }
- #else
- ret = SDC_SemPend(&host->lock, SDC_DMA_TIMEOUT);
- #endif
- if (ret != HAL_OK && host->present){
- uint32_t sg_len = data->sg_len;
- uint32_t i;
- uint32_t rval = 0;
- SDC_LOGE("sdc cmd:%ld, wait command done timeout !!\n",
- HAL_PR_SZ_L(host->smc_cmd & SDXC_CMD_OPCODE));
- host->debug_mask |= ROM_DUMP_MASK | ROM_ERR_MASK;
- #if 1
- __mci_force_dump_host_info(host);
- if (data) {
- SDC_LOGE("dump data blksz %ld,blocks %ld,flags %lx\n", HAL_PR_SZ_L(data->blksz), HAL_PR_SZ_L(data->blocks), HAL_PR_SZ_L(data->flags));
- }
- #endif
- SDC_LOGE("%s,%d\n",__FUNCTION__,__LINE__);
- for (i = 0; i < sg_len; i++) {
- struct scatterlist *sg = data->sg;
- uint32_t *buf_temp = (uint32_t *)sg[i].buffer;
- #ifdef CONFIG_SDC_DMA_USED
- if (HAL_PT_TO_U(sg[i].buffer) & 0x03) {
- sdc_use_dma = 0;
- SDC_LOGW("%s,%d\n",__FUNCTION__,__LINE__);
- break;
- }
- SDC_LOGE("%s,%d\n",__FUNCTION__,__LINE__);
- HAL_InvalidDcacheRegion((unsigned long )(sg[i].buffer), HAL_ALIGN(sg[i].len, OS_CACHE_ALIGN_BYTES));
- SDC_LOGE("%s,%d\n",__FUNCTION__,__LINE__);
- SDC_LOGE("buf addr %lx buffer0 %x buffer1 %x\n", HAL_PR_SZ_L(sg[i].buffer), (unsigned int)buf_temp[0],(unsigned int) buf_temp[1]);
- #endif
- }
- SDC_LOGE("%s,%d\n",__FUNCTION__,__LINE__);
- mci_writel(0xdeb, host, SDXC_REG_TMOUT);
- SDC_LOGE("*force wr smc timeout reg %x*\n",(unsigned int)mci_readl(host, SDXC_REG_TMOUT));
- #if 1
- SDC_LOGE("*force dump sram*\n");
- rval = readl(0x03000000+0x0048);
- rval |= 1 << 4;
- writel(rval, 0x03000000+0x0048);
- sdc_hex_dump_word((void *)SMC1_BASE ,0x100);
- #endif
- SDC_LOGE("%s,%d\n",__FUNCTION__,__LINE__);
- SDC_BUG_ON(1);
- sys_abort();
- /*sdc_hex_dump_word((void *)0x4002000 ,0x200);*/
- host->debug_mask &= ~ROM_DUMP_MASK;
- goto out;
- }
- ret = __mci_request_done(host);
- if (ret) {
- goto out;
- }
- out:
- /* enable debounce */
- __mci_debounce_onoff(host, 1);
- if(data && (data->flags & MMC_DATA_READ )){
- uint32_t i;
- uint32_t byte_cnt = 0;
- struct scatterlist *sg = data->sg;
- uint32_t sg_len = data->sg_len;
- for (i = 0; i < sg_len; i++) {
- byte_cnt += sg[i].len;
- #ifdef CONFIG_SDC_DMA_USED
- if (HAL_PT_TO_U(sg[i].buffer) & 0x03) {
- sdc_use_dma = 0;
- break;
- }
- HAL_InvalidDcacheRegion((unsigned long)(sg[i].buffer), HAL_ALIGN(sg[i].len, OS_CACHE_ALIGN_BYTES));
- #endif
- }
- }
- SDC_MutexUnlock(&host->thread_lock);
- #ifdef SD_PERF_TRACE_ON
- __mci_end_data_time_stats(host, mrq);
- #endif
- return ret;
- }
- int32_t rom_HAL_SDC_Request(struct mmc_host *host, struct mmc_request *mrq)
- {
- int32_t ret = 0;
- #ifdef CONFIG_SDC_DMA_USED
- uint32_t sdc_use_dma_buf = 0;
- struct scatterlist sg_dma = {0};
- struct scatterlist *sg = NULL;
- uint32_t sg_len = 0;
- struct mmc_data *data;
- uint32_t i = 0;
- uint32_t byte_cnt = 0;
- unsigned long addr = 0;
- uint32_t len = 0;
- if (mrq->data) {
- data = mrq->data;
- sg_len = data->sg_len;
- sg = data->sg;
- for (i = 0; i < sg_len; i++) {
- addr = HAL_PT_TO_U(sg[i].buffer);
- len = sg[i].len;
- byte_cnt += sg[i].len;
- if ((addr & 0x03)\
- || (addr & (OS_CACHE_ALIGN_BYTES - 1))
- || (len & (OS_CACHE_ALIGN_BYTES - 1))) {
- sdc_use_dma_buf = 1;
- SDC_LOGD("try to use dma debounce buff, addr %lx, len %ld\n", \
- HAL_PR_SZ_L(addr), HAL_PR_SZ_L(byte_cnt));
- }
- }
- if (sdc_use_dma_buf) {
- if (byte_cnt > SDC_ALIGN_DMA_BUF_SIZE) {
- SDC_LOGE("byte count %ld over dma debounce buf size %d\n", \
- HAL_PR_SZ_L(byte_cnt), SDC_ALIGN_DMA_BUF_SIZE);
- return -1;
- } else if (byte_cnt < SDC_MAX_CPU_TRANS_LEN) {
- SDC_LOGD("byte cnt %ld is too small not use dma align buf\n", \
- HAL_PR_SZ_L(byte_cnt));
- sdc_use_dma_buf = 0;
- } else {
- uint32_t total_len = 0;
- if (data->flags & MMC_DATA_WRITE) {
- for (i = 0; i < sg_len; i++) {
- addr = HAL_PT_TO_U(sg[i].buffer);
- len = sg[i].len;
- HAL_Memcpy((char *)(host->align_dma_buf + total_len), (char *)addr, len);
- total_len += len;
- }
- }
- sg_dma.buffer = host->align_dma_buf;
- sg_dma.len = byte_cnt;
- data->sg = &sg_dma;
- data->sg_len = 1;
- SDC_LOGD("use dma debounce buff addr %lx, len %d, align_dma_buf %lx\n", \
- HAL_PT_TO_U(sg[0].buffer),\
- (unsigned int)byte_cnt,\
- HAL_PT_TO_U(host->align_dma_buf));
- }
- }
- }
- #endif
- ret = do_rom_HAL_SDC_Request(host, mrq);
- #ifdef CONFIG_SDC_DMA_USED
- if(!ret && data && sdc_use_dma_buf) {
- if (data->flags & MMC_DATA_READ) {
- uint32_t total_len = 0;
- for (i = 0; i < sg_len; i++) {
- addr = HAL_PT_TO_U(sg[i].buffer);
- len = sg[i].len;
- HAL_Memcpy((char *)addr, (char *)(host->align_dma_buf + total_len), len);
- total_len += len;
- }
- SDC_LOGD("copy back to dst buffer%ld\n", HAL_PR_SZ_L(byte_cnt));
- }
- data->sg = sg;
- data->sg_len = sg_len;
- }
- #endif
- return ret;
- }
- #ifdef CONFIG_SDC_EXCLUSIVE_HOST
- /**
- * HAL_SDC_Claim_Host - exclusively claim a host
- * @host: mmc host to claim
- *
- * Claim a host for a set of operations.
- */
- int32_t HAL_SDC_Claim_Host(struct mmc_host *host)
- {
- return (SDC_SemPend(&host->exclusive_lock, OS_WAIT_FOREVER) == OS_OK ? 0 : -1);
- }
- /**
- * HAL_SDC_Release_Host - release a host
- * @host: mmc host to release
- *
- * Release a MMC host, allowing others to claim the host
- * for their operations.
- */
- void HAL_SDC_Release_Host(struct mmc_host *host)
- {
- SDC_SemPost(&host->exclusive_lock);
- }
- #endif
- #ifdef CONFIG_SDC_READONLY_USED
- int32_t HAL_SDC_Get_ReadOnly(struct mmc_host *host)
- {
- uint32_t wp_val;
- GPIO_PinMuxParam *ro_gpio = &host->ro_gpio;
- wp_val = (GPIO_PIN_HIGH == HAL_GPIO_ReadPin(ro_gpio->port, ro_gpio->pin)) ? 1 : 0;
- SDC_LOGN("sdc fetch card wp pin status: %u\n", (unsigned int)wp_val);
- if (!wp_val) {
- host->read_only = 0;
- return 0;
- } else {
- SDC_LOGN("Card is write-protected\n");
- host->read_only = 1;
- return 1;
- }
- return 0;
- }
- #endif
- #ifdef CONFIG_DETECT_CARD
- static irqreturn_t __mci_cd_irq(int unuse, void *arg);
- static void __mci_enable_cd_pin_irq(struct mmc_host *host)
- {
- //SDC_LOGD("Not implement %s,%d\n", __FUNCTION__,__LINE__);
- //SDC_ENABLE_IRQ(host->cd_irq);
- hal_gpio_irq_enable(host->cd_irq);
- }
- static void __mci_disable_cd_pin_irq(struct mmc_host *host)
- {
- // HAL_GPIO_DisableIRQ(host->cd_port, host->cd_pin);
- // SDC_LOGE("Not implement %s,%d\n", __FUNCTION__,__LINE__);
- //SDC_DISABLE_IRQ(host->cd_irq);
- hal_gpio_irq_disable(host->cd_irq);
- }
- static void __mci_voltage_stable_det(void *arg)
- {
- struct mmc_host *host = (struct mmc_host *)arg;
- if (!host->present || host->wait_voltage_stable || !host->cd_delay) {
- host->wait_voltage_stable = 0;
- __mci_enable_cd_pin_irq(host);
- host->param.cd_cb(host->present);
- } else {
- SDC_ModTimer(&host->cd_timer, host->cd_delay);
- host->wait_voltage_stable = 1;
- }
- }
- static void __mci_cd_timer(void *arg)
- {
- struct mmc_host *host = (struct mmc_host *)arg;
- uint32_t gpio_val = 0;
- uint32_t present;
- gpio_val = (host->cd_pin_present_val == HAL_GPIO_ReadPin(host->cd_gpio_pin, &gpio_val)) ? 1 : 0;
- //SDC_LOGE("Not implement %s,%d\n", __FUNCTION__,__LINE__);
- if (gpio_val) {
- present = 1;
- } else {
- present = 0;
- }
- SDC_LOGD("cd %lu, host present %lu, cur present %lu\n",
- HAL_PR_SZ_L(gpio_val), HAL_PR_SZ_L(host->present), HAL_PR_SZ_L(present));
- if (host->present ^ present || host->wait_voltage_stable) {
- SDC_LOGD("sdc detect change, present %lu\n", HAL_PR_SZ_L(present));
- host->present = present;
- __mci_voltage_stable_det(host);
- }
- else {
- __mci_enable_cd_pin_irq(host);
- }
- __sdc_init_timeout_flags = 1;
- return ;
- }
- static void __mci_dat3_det(void *arg)
- {
- struct mmc_host *host = (struct mmc_host *)arg;
- SDC_LOGD("***dat3 det***\n");
- __mci_voltage_stable_det(host);
- }
- static irqreturn_t __mci_cd_irq(int unuse, void *arg)
- {
- struct mmc_host *host = (struct mmc_host *)arg;
- SDC_LOGD("***in cd***\n");
- if (!SDC_TimerIsActive(&host->cd_timer) || host->wait_voltage_stable) {
- host->wait_voltage_stable = 0;
- SDC_ModTimer(&host->cd_timer, 10);
- __mci_disable_cd_pin_irq(host);
- }
- return (irqreturn_t)NULL;
- }
- #endif
- int32_t rom_HAL_SDC_PowerOn(struct mmc_host *host)
- {
- uint32_t rval;
- if (!host) {
- SDC_LOGE_RAW(ROM_ERR_MASK, "%s,%d err", __func__, __LINE__);
- return -1;
- }
- SDC_LOGD("MMC Driver init host\n");
- __mci_restore_io(host);
- __mci_clk_prepare_enable(host);
- /* delay 1ms ? */
- __mci_update_clock(host, 400000);
- host->clk = 400000;
- /* reset controller*/
- rval = mci_readl(host, SDXC_REG_GCTRL)|SDXC_HWReset|SDXC_INTEnb|
- SDXC_AccessDoneDirect;
- mci_writel(rval, host, SDXC_REG_GCTRL);
- __mci_check_bit_clear(host, SDXC_REG_GCTRL, SDXC_HWReset);
- SDC_LOGD("%s,%d\n",__FUNCTION__,__LINE__);
- mci_writel(0xffffffff, host, SDXC_REG_RINTR);
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode == CARD_DETECT_BY_D3) {
- mci_writel(SDXC_CardInsert|SDXC_CardRemove|host->sdio_irq_mask, host, SDXC_REG_IMASK);
- } else
- #endif
- {
- mci_writel(host->sdio_irq_mask, host, SDXC_REG_IMASK);
- }
- #define SDMC_DATA_TIMEOUT 0x0ffffffU
- #define SDMC_RESP_TIMEOUT 0xffU
- /* Set Data & Response Timeout Value */
- mci_writel((SDMC_DATA_TIMEOUT<<8)|SDMC_RESP_TIMEOUT, host, SDXC_REG_TMOUT);
- #undef SDMC_RESP_TIMEOUT
- #undef SDMC_DATA_TIMEOUT
- HAL_SDC_Set_BusWidth(host, MMC_BUS_WIDTH_1);
- #ifdef SDC_DEBUG
- mci_writel(0xdeb, host, SDXC_REG_DBGC);
- mci_writel(0xceaa0000, host, SDXC_REG_FUNS);
- #endif
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode == CARD_DETECT_BY_D3){
- rval |= SDXC_DebounceEnb;
- }
- mci_writel(rval, host, SDXC_REG_GCTRL);
- #endif
- if (host->sdc_id == 0) {
- SDC_ENABLE_IRQ(SDC0_IRQn);
- }
- #if SDC1_SUPPORT
- else if (host->sdc_id == 1)
- SDC_ENABLE_IRQ(SDC1_IRQn);
- #endif
- host->power_on = 1;
- return 0;
- }
- int32_t rom_HAL_SDC_PowerOff(struct mmc_host *host)
- {
- if (!host) {
- SDC_LOGE_RAW(ROM_ERR_MASK, "%s,%d err", __func__, __LINE__);
- return -1;
- }
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode != CARD_DETECT_BY_D3)
- #endif
- {
- uint32_t rval;
- if (host->sdc_id == 0)
- SDC_DISABLE_IRQ(SDC0_IRQn);
- #if SDC1_SUPPORT
- else if (host->sdc_id == 1)
- SDC_DISABLE_IRQ(SDC1_IRQn);
- #endif
- rval = mci_readl(host, SDXC_REG_GCTRL) | SDXC_HWReset;
- mci_writel(rval, host, SDXC_REG_GCTRL);
- __mci_check_bit_clear(host, SDXC_REG_GCTRL, SDXC_HWReset);
- rval = mci_readl(host, SDXC_REG_MISTA);
- mci_writel(rval & (~SDXC_SDIOInt), host, SDXC_REG_RINTR);
- if (host->sdc_id == 0)
- SDC_CLEAR_IRQPINGD(SDC0_IRQn);
- #if SDC1_SUPPORT
- else if (host->sdc_id == 1)
- SDC_CLEAR_IRQPINGD(SDC1_IRQn);
- #endif
- __mci_clk_disable_unprepare(host);
- __mci_hold_io(host);
- host->power_on = 0;
- }
- return 0;
- }
- #ifdef CONFIG_SD_PM
- static void __mci_regs_save(struct mmc_host *host)
- {
- struct __mci_ctrl_regs *bak_regs = &host->regs_back;
- bak_regs->gctrl = mci_readl(host, SDXC_REG_GCTRL);
- bak_regs->clkc = mci_readl(host, SDXC_REG_CLKCR);
- bak_regs->timeout = mci_readl(host, SDXC_REG_TMOUT);
- bak_regs->buswid = mci_readl(host, SDXC_REG_WIDTH);
- bak_regs->waterlvl = mci_readl(host, SDXC_REG_FTRGL);
- bak_regs->funcsel = mci_readl(host, SDXC_REG_FUNS);
- bak_regs->idmacc = mci_readl(host, SDXC_REG_DMAC);
- }
- static void __mci_regs_restore(struct mmc_host *host)
- {
- struct __mci_ctrl_regs* bak_regs = &host->regs_back;
- mci_writel(bak_regs->gctrl, host, SDXC_REG_GCTRL);
- mci_writel(bak_regs->clkc, host, SDXC_REG_CLKCR);
- mci_writel(bak_regs->timeout, host, SDXC_REG_TMOUT);
- mci_writel(bak_regs->buswid, host, SDXC_REG_WIDTH);
- mci_writel(bak_regs->waterlvl, host, SDXC_REG_FTRGL);
- mci_writel(bak_regs->funcsel, host, SDXC_REG_FUNS);
- #ifdef SDC_DEBUG
- mci_writel(0xdeb, host, SDXC_REG_DBGC);
- mci_writel(0xceaa0000, host, SDXC_REG_FUNS);
- #endif
- mci_writel(bak_regs->idmacc, host, SDXC_REG_DMAC);
- }
- static int __mci_suspend(struct soc_device *dev, enum suspend_state_t state)
- {
- int ret = 0;
- struct mmc_host *host = dev->platform_data;
- uint32_t _timeout = HAL_Ticks() + HAL_MSecsToTicks(SDC_DMA_TIMEOUT) + 1;
- if (host->bus_ops && host->bus_ops->suspend)
- ret = host->bus_ops->suspend(host);
- if (ret) {
- if (host->bus_ops->resume)
- host->bus_ops->resume(host);
- SDC_LOGE("%s bus id:%d faild\n", __func__, host->sdc_id);
- goto err;
- }
- host->suspend = 1;
- while ((host->wait != SDC_WAIT_NONE) && HAL_TimeBefore(HAL_Ticks(), _timeout)) {
- }
- if (HAL_TimeAfterEqual(HAL_Ticks(), _timeout) && (host->wait != SDC_WAIT_NONE)) {
- ret = -1;
- host->suspend = 0;
- if (host->bus_ops && host->bus_ops->resume)
- ret = host->bus_ops->resume(host);
- SDC_LOGE("%s id:%d faild\n", __func__, host->sdc_id);
- goto err;
- }
- __mci_regs_save(host);
- /* gate clock for lower power */
- if (host->sdc_id == 0) {
- SDC0_DisableMClock();
- SDC0_CCM_BusForceReset();
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- SDC1_DisableMClock();
- SDC1_CCM_BusForceReset();
- #endif
- }
- __mci_clk_disable_unprepare(host);
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode == CARD_DETECT_BY_D3) {
- __mci_exit_host(host);
- if (host->sdc_id == 0) {
- SDC0_DisableMClock();
- SDC0_CCM_BusForceReset();
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- SDC1_DisableMClock();
- SDC1_CCM_BusForceReset();
- #endif
- }
- __mci_hold_io(host);
- SDC_LOGD("sdc card_power_off ok\n");
- //__mci_set_vddio(host, SDC_WOLTAGE_OFF);
- //usleep_range(1000, 1500);
- host->power_on = 0;
- }
- #endif
- SDC_LOGD("%s id:%d ok\n", __func__, host->sdc_id);
- err:
- return ret;
- }
- static int __mci_resume(struct soc_device *dev, enum suspend_state_t state)
- {
- int ret = 0;
- struct mmc_host *host = dev->platform_data;
- uint32_t clk = host->clk;
- __mci_restore_io(host);
- if (host->sdc_id == 0) {
- SDC0_CCM_BusForceReset();
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- SDC1_CCM_BusForceReset();
- #endif
- }
- __mci_clk_disable_unprepare(host);
- mmc_udelay(35);
- /* enable clock for resotre */
- __mci_clk_prepare_enable(host);
- mmc_udelay(50);
- __mci_update_clock(host, clk);
- mmc_udelay(100);
- __mci_regs_restore(host);
- #ifdef CONFIG_DETECT_CARD
- #else
- mci_writel(SDXC_CardInsert, host, SDXC_REG_RINTR);
- #endif
- __mci_update_clk(host);
- /* register IRQ */
- if (host->sdc_id == 0)
- SDC_CONFIG_IRQ(SDC0_IRQn, &SDC0_IRQHandler, NVIC_PERIPH_PRIO_DEFAULT);
- #if SDC1_SUPPORT
- else if (host->sdc_id == 1)
- SDC_CONFIG_IRQ(SDC1_IRQn, &SDC1_IRQHandler, NVIC_PERIPH_PRIO_DEFAULT);
- #endif
- mmc_udelay(100);
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode == CARD_DETECT_BY_GPIO_IRQ)
- __mci_cd_timer(host);
- if (host->param.cd_mode == CARD_DETECT_BY_D3) {
- uint32_t rval = 0;
- //__mci_set_vddio(host, host->regulator_voltage);
- //usleep_range(1000, 1500);
- host->power_on = 1;
- __mci_restore_io(host);
- __mci_clk_prepare_enable(host);
- mmc_mdelay(1);
- rval = mci_readl(host, SDXC_REG_RINTR);
- SDC_LOGD(">> REG_RINTR=0x%x\n", (unsigned int)rval);
- (void)rval;
- }
- #endif
- host->suspend = 0;
- if (host->bus_ops && host->bus_ops->resume)
- ret = host->bus_ops->resume(host);
- SDC_LOGD("%s id:%d ok\n", __func__, host->sdc_id);
- return ret;
- }
- static const struct soc_device_driver sdc_drv = {
- .name = "sdc",
- .suspend = __mci_suspend,
- .resume = __mci_resume,
- };
- static struct soc_device sdc_dev[SDC_NUM] = {
- { .name = "sdc0", .driver = &sdc_drv, },
- { .name = "sdc1", .driver = &sdc_drv, }
- };
- #define SDC_DEV(id) (&sdc_dev[id])
- #endif /* CONFIG_SD_PM */
- int hal_sdc_init_timeout(void)
- {
- return __sdc_init_timeout_flags;
- }
- /**
- * @brief Initializes the SDC peripheral.
- * @param sdc_id:
- * @arg sdc_id->SDC ID.
- * @param param:
- * @arg param->[in] The configuration information.
- * @retval SDC handler.
- */
- struct mmc_host *hal_sdc_init(struct mmc_host *host)
- {
- __sdc_init_timeout_flags = 0;
- #ifdef __CONFIG_ARCH_APP_CORE
- const HAL_SDCGPIOCfg *sd_gpio_cfg = NULL;
- const HAL_SDCGPIOCfg sd_gpio_cfg_entry;
- sd_gpio_cfg = &sd_gpio_cfg_entry;
- #endif
- int ret = 0;
- if (host->State != SDC_STATE_RESET) {
- SDC_LOGW("%s----%d reinit sdc!\n", __func__,__LINE__);
- return NULL;
- }
- if (host->sdc_id == 0) {
- host->reg_base = (volatile void *)SMC0_BASE;
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- host->reg_base = (volatile void *)SMC1_BASE;
- #endif
- } else {
- SDC_LOGW("%s unsupport sdc id:%d!\n", __func__, host->sdc_id);
- return NULL;
- }
- #ifdef __CONFIG_PLATFORM_FPGA
- host->caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_WAIT_WHILE_BUSY |
- MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50;
- if (HAL_GetDevClock() > 25000000) {
- host->caps |= MMC_CAP_SD_HIGHSPEED;
- }
- #else
- host->caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_WAIT_WHILE_BUSY | \
- MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50|MMC_CAP_SDIO_IRQ;
- if (host->param.low_speed)
- host->caps &= ~(MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED);
- #endif
- #ifdef CONFIG_SD_PM
- host->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
- #endif
- #ifdef __CONFIG_ARCH_APP_CORE
- #ifdef NUSE_STANDARD_INTERFACE
- if (host->sdc_id == 0) {
- #ifndef SDC_FPGA
- sdmmc_pinctrl_init(host);
- #endif
- host->caps |= MMC_CAP_4_BIT_DATA;
- } else if (host->sdc_id == 1) {
- sdmmc_pinctrl_init(host);
- #if 0
- SDC1_SET_GPIO_PULL();
- SDC1_SET_GPIO_DRV();
- SDC1_SET_GPIO_MUX();
- #endif
- host->caps &= ~MMC_CAP_4_BIT_DATA;
- }
- #else
- HAL_BoardIoctl(HAL_BIR_GET_CFG, HAL_MKDEV(HAL_DEV_MAJOR_SDC, host->sdc_id),
- (uint32_t)&sd_gpio_cfg);
- /*test gpio_detect by gpio irq*/
- sd_gpio_cfg->has_detect_gpio = 1;
- if (!sd_gpio_cfg)
- host->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA;
- else if (sd_gpio_cfg->data_bits == 8)
- host->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA;
- else if (sd_gpio_cfg->data_bits == 4)
- host->caps |= MMC_CAP_4_BIT_DATA;
- #endif
- #else
- host->caps |= MMC_CAP_4_BIT_DATA;
- #endif
- __mci_restore_io(host);
- host->clk = 400000;
- /* register IRQ */
- if (host->sdc_id == 0) {
- ret = SDC_REQUEST_IRQ(SDC0_IRQn, SDC0_IRQHandler, host);
- if (ret != 0) {
- SDC_LOGE("%s,%d err:%d\n",__func__, __LINE__, ret);
- return NULL;
- }
- SDC_SetPriority(SDC0_IRQn, NVIC_PERIPH_PRIO_DEFAULT);
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- ret = SDC_REQUEST_IRQ(SDC1_IRQn, SDC1_IRQHandler, host);
- if (ret != 0) {
- SDC_LOGE("%s,%d err:%d\n",__func__, __LINE__, ret);
- return NULL;
- }
- SDC_SetPriority(SDC1_IRQn, NVIC_PERIPH_PRIO_DEFAULT);
- #endif
- }
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode == CARD_ALWAYS_PRESENT) {
- host->present = 1;
- } else if (host->param.cd_mode == CARD_DETECT_BY_GPIO_IRQ) {
- #if 0
- if (!sd_gpio_cfg || (!sd_gpio_cfg->has_detect_gpio)) {
- SDC_LOGE("%s,%d cd_mode:%ld with no detect_gpio!\n",
- __func__, __LINE__, host->param.cd_mode);
- return NULL;
- }
- #endif
- //host->cd_port = sd_gpio_cfg->detect_port;
- //host->cd_pin = sd_gpio_cfg->detect_pin;
- //host->cd_pin_present_val = sd_gpio_cfg->detect_pin_present_val;
- #ifndef CONFIG_DRIVERS_SDC_CDPIN_PRESENT_VAL
- #define CONFIG_DRIVERS_SDC_CDPIN_PRESENT_VAL 0
- #endif
- host->cd_pin_present_val = CONFIG_DRIVERS_SDC_CDPIN_PRESENT_VAL;
- //HAL_BoardIoctl(HAL_BIR_PINMUX_INIT, HAL_MKDEV(HAL_DEV_MAJOR_SDC,
- // host->sdc_id), SDCGPIO_DET);
- SDC_LOGN("%s,%d no imp\n",__func__, __LINE__);
- //host->cd_delay = sd_gpio_cfg->detect_delay;
- host->cd_delay = 10; /* short delay */
- SDC_InitTimer(&host->cd_timer, &__mci_cd_timer, host, 10);
- //HAL_GPIO_SetDebounce(&Irq_param, (2U << 4) | 1); /* set debounce clock */
- __mci_enable_cd_pin_irq(host);
- SDC_LOGN("%s,%d no imp\n",__func__, __LINE__);
- host->present = (host->cd_pin_present_val ==
- HAL_GPIO_ReadPin(host->cd_gpio_pin, &host->present)) ? 1 : 0;
- //host->present = 1;
- } else if (host->param.cd_mode == CARD_DETECT_BY_D3) {
- uint32_t rval;
- //host->cd_delay = sd_gpio_cfg->detect_delay;
- host->cd_delay = 100;
- __mci_clk_prepare_enable(host);
- mmc_mdelay(1);
- host->present = 1;
- rval = mci_readl(host, SDXC_REG_RINTR);
- SDC_LOGD("sdc +> REG_RINTR=0x%x\n", (unsigned int)rval);
- if ((rval & SDXC_CardRemove)) {
- SDC_LOGD("sdc data[3] detect Card Remove\n");
- host->present = 0;
- }
- SDC_InitTimer(&host->cd_timer, &__mci_dat3_det, host, 300);
- }
- #else
- host->present = 1;
- #endif
- host->align_dma_buf = HAL_MallocAlign(SDC_ALIGN_DMA_BUF_SIZE);
- host->idma_des = HAL_MallocAlign(HAL_ALIGN(SDXC_MAX_DES_NUM * sizeof(smc_idma_des), OS_CACHE_ALIGN_BYTES));
- if (HAL_PT_TO_U(host->idma_des) & 0x07U) {
- SDC_LOGE_RAW(ROM_ERR_MASK, "%s malloc not aligned by 8B\n", __func__);
- return NULL;
- }
- SDC_LOGD("idma_des %lx\n",HAL_PR_SZ_L(host->idma_des));
- host->max_blk_count = 8192;
- host->max_blk_size = 4096;
- host->max_req_size = host->max_blk_size * host->max_blk_count;
- host->max_seg_size = host->max_req_size;
- host->max_segs = 128;
- host->ocr_avail = MMC_VDD_28_29 | MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32
- | MMC_VDD_32_33 | MMC_VDD_33_34;
- SDC_LOGN("SDC Host Capability:0x%x Ocr avail:0x%x\n", (unsigned int)host->caps, (unsigned int)host->ocr_avail);
- /* init semaphore */
- SDC_SemCreate(&host->lock, 0);
- SDC_MutexCreate(&host->thread_lock);
- #ifdef CONFIG_SDC_EXCLUSIVE_HOST
- SDC_SemCreate(&host->exclusive_lock, 1);
- #endif
- #ifdef CONFIG_DETECT_CARD
- if (host->param.cd_mode == CARD_DETECT_BY_D3 && host->present == 0) {
- SDC_LOGD("SDC power init.\n");
- HAL_SDC_PowerOn(host);
- } else if (host->present == 0) {
- /* if card is not present and the card detect mode is not CARD_DETECT_BY_D3,
- * we shutdown io voltage to save power. */
- SDC_LOGD("SDC no card detected, shutdown io voltage.\n");
- __mci_hold_io(host);
- //__mci_set_vddio(host, SDC_VOLTAGE_OFF);
- }
- #endif
- #ifdef CONFIG_SD_PM
- SDC_DEV(host->sdc_id)->platform_data = host;
- pm_register_ops(SDC_DEV(host->sdc_id));
- #endif
- host->State = SDC_STATE_READY;
- host->wait = SDC_WAIT_NONE;
- #ifdef CONFIG_DETECT_CARD
- //if (host->param.cd_mode != CARD_ALWAYS_PRESENT && host->present) {
- if (host->param.cd_mode != CARD_ALWAYS_PRESENT) {
- host->wait_voltage_stable = 1;
- if (host->cd_delay == 0) {
- SDC_ModTimer(&host->cd_timer, 10);
- } else {
- SDC_ModTimer(&host->cd_timer, host->cd_delay);
- }
- }
- SDC_LOGN("SDC cd_mode:%d present_val:%d\n", (unsigned int)host->param.cd_mode,
- (unsigned int)host->cd_pin_present_val);
- #endif
- SDC_LOGN("SDC id:%d dma_use:%d present:%d\n driver version %s init ok.\n", (unsigned int)host->sdc_id,
- (unsigned int)host->dma_use, (unsigned int)host->present ,SDMMC_DRIVER_VERSION);
- #ifdef SDC_FPGA
- SDC_LOGN("SDC ***Warning: use FPGA config,Are you sure?***\n wmb,cache unsupport now\n");
- #endif
- sdc_hex_dump_word((const void *)(SDC_GPIO_BASE+0xb0),0x400);
- sdc_hex_dump_word((const void *)0x4002000, 0x200);
- return host;
- }
- /**
- * @brief DeInitializes the SDC peripheral.
- * @param sdc_id:
- * @arg sdc_id-> SDC ID.
- * @retval None.
- */
- int32_t hal_sdc_deinit(uint32_t sdc_id)
- {
- struct mmc_host *host = _mci_host[sdc_id];
- if (!host) {
- SDC_LOGE_RAW(ROM_ERR_MASK, "%s,%d err", __func__, __LINE__);
- return -1;
- }
- #ifdef CONFIG_DETECT_CARD
- host->param.cd_mode = 0;
- #endif
- #ifdef CONFIG_SD_PM
- pm_unregister_ops(SDC_DEV(host->sdc_id));
- #endif
- __mci_exit_host(host);
- if (host->sdc_id == 0) {
- SDC0_DisableMClock();
- SDC0_CCM_BusForceReset();
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- SDC1_DisableMClock();
- SDC1_CCM_BusForceReset();
- #endif
- }
- #ifdef CONFIG_DETECT_CARD
- HAL_BoardIoctl(HAL_BIR_PINMUX_DEINIT, HAL_MKDEV(HAL_DEV_MAJOR_SDC,
- host->sdc_id), SDCGPIO_DET);
- #endif
- #ifdef CONFIG_SDC_EXCLUSIVE_HOST
- SDC_SemDel(&host->exclusive_lock);
- #endif
- SDC_MutexDelete(&host->thread_lock);
- SDC_SemDel(&host->lock);
- HAL_FreeAlign(host->idma_des);
- HAL_FreeAlign(host->align_dma_buf);
- #ifdef CONFIG_DETECT_CARD
- if ((host->param.cd_mode == CARD_DETECT_BY_GPIO_IRQ)||
- (host->param.cd_mode == CARD_DETECT_BY_D3)) {
- SDC_DelTimer(&host->cd_timer);
- }
- #endif
- if (host->sdc_id == 0) {
- SDC_FREE_IRQ(SDC0_IRQn, host);
- #if SDC1_SUPPORT
- } else if (host->sdc_id == 1) {
- SDC_FREE_IRQ(SDC1_IRQn, host);
- #endif
- }
- SDC_LOGD("sdc:%ld deinit ok.\n", HAL_PR_SZ_L(sdc_id));
- return 0;
- }
- /**
- * @brief malloc for sd host.
- * @param sdc_id:
- * @arg host ID.
- * @retval 0 if success or other if failed.
- */
- struct mmc_host *hal_sdc_create(uint32_t sdc_id, SDC_InitTypeDef *param)
- {
- struct mmc_host *host = _mci_host[sdc_id];
- int ret;
- rt_kprintf("hal_sdc_create %d\n",sdc_id);
- if (host) {
- SDC_LOGE_RAW(ROM_ERR_MASK, "%s has already created!\n", __func__);
- return host;
- }
- host = HAL_Malloc(sizeof(struct mmc_host));
- if (host == NULL) {
- SDC_LOGE_RAW(ROM_ERR_MASK, "%s malloc fail\n", __func__);
- } else {
- SDC_Memset(host, 0, sizeof(struct mmc_host));
- host->sdc_id = sdc_id;
- host->ref = 0;
- #ifdef __CONFIG_ARCH_APP_CORE
- memcpy(&host->param, param, sizeof(SDC_InitTypeDef));
- host->debug_mask = param->debug_mask;
- host->dma_use = param->dma_use;
- #ifdef CONFIG_DETECT_CARD
- if (param->cd_mode == CARD_DETECT_BY_GPIO_IRQ || param->cd_mode == CARD_DETECT_BY_D3) {
- host->cd_gpio_isr = __mci_cd_irq;
- ret = mmc_gpiod_request_cd_irq(host);
- if (!param->cd_cb && ret < 0) {
- HAL_Free(host);
- SDC_LOGE("%s,%d cd_mode:%ld with no cb!\n",
- __func__, __LINE__, HAL_PR_SZ_L(param->cd_mode));
- return NULL;
- }
- }
- #endif
- #endif
- _mci_host[sdc_id] = host;
- SDC_LOGN("%s host:%p id:%d\n", __func__, host, host->sdc_id);
- }
- return host;
- }
- /**
- * @brief free for sd host.
- * @param host:
- * @arg host ID.
- * @param flg:
- * @arg 0:normal delete, 1:unnormal delete, internal use.
- * @retval 0 if success or other if failed.
- */
- int32_t hal_sdc_destroy(struct mmc_host *host)
- {
- if (host == NULL) {
- SDC_LOGW_RAW(ROM_WRN_MASK, "%s host not exit!\n", __func__);
- return -1;
- }
- if (host->ref != 0) {
- SDC_LOGW("%s fail, ref:%d\n", __func__, host->ref);
- return -1;
- }
- _mci_host[host->sdc_id] = NULL;
- SDC_LOGD("%s host:%p id:%d\n", __func__, host, host->sdc_id);
- HAL_Free(host);
- return 0;
- }
- /**
- * @brief get pointer of mmc_host.
- * @param sdc_id:
- * @arg host ID.
- * @retval pointer of mmc_card if success or NULL if failed.
- */
- struct mmc_host *hal_sdc_open(uint32_t sdc_id)
- {
- struct mmc_host *host = _mci_host[sdc_id];
- if (host == NULL || host->sdc_id != sdc_id) {
- SDC_LOGW_RAW(ROM_WRN_MASK, "%s host not exit! id:%d,host:%x\n", __func__, (unsigned int)sdc_id, HAL_PR_SZ(HAL_PT_TO_U(host)));
- return NULL;
- }
- host->ref++;
- return host;
- }
- /**
- * @brief close mmc_host.
- * @param host_id:
- * @arg host ID.
- * @retval 0 if success or other if failed.
- */
- uint32_t hal_sdc_close(uint32_t sdc_id)
- {
- struct mmc_host *host = _mci_host[sdc_id];
- if (host == NULL || host->sdc_id != sdc_id || host->ref < 1) {
- SDC_LOGW_RAW(ROM_WRN_MASK, "%s fail! id:%ld\n", __func__, HAL_PR_SZ_L(sdc_id));
- return -1;
- }
- host->ref--;
- return 0;
- }
|