omap1.c 117 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053
  1. /*
  2. * TI OMAP processors emulation.
  3. *
  4. * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 or
  9. * (at your option) version 3 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "hw.h"
  20. #include "arm-misc.h"
  21. #include "omap.h"
  22. #include "sysemu.h"
  23. #include "soc_dma.h"
  24. #include "blockdev.h"
  25. #include "range.h"
  26. #include "sysbus.h"
  27. /* Should signal the TCMI/GPMC */
  28. uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
  29. {
  30. uint8_t ret;
  31. OMAP_8B_REG(addr);
  32. cpu_physical_memory_read(addr, (void *) &ret, 1);
  33. return ret;
  34. }
  35. void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
  36. uint32_t value)
  37. {
  38. uint8_t val8 = value;
  39. OMAP_8B_REG(addr);
  40. cpu_physical_memory_write(addr, (void *) &val8, 1);
  41. }
  42. uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
  43. {
  44. uint16_t ret;
  45. OMAP_16B_REG(addr);
  46. cpu_physical_memory_read(addr, (void *) &ret, 2);
  47. return ret;
  48. }
  49. void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
  50. uint32_t value)
  51. {
  52. uint16_t val16 = value;
  53. OMAP_16B_REG(addr);
  54. cpu_physical_memory_write(addr, (void *) &val16, 2);
  55. }
  56. uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
  57. {
  58. uint32_t ret;
  59. OMAP_32B_REG(addr);
  60. cpu_physical_memory_read(addr, (void *) &ret, 4);
  61. return ret;
  62. }
  63. void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
  64. uint32_t value)
  65. {
  66. OMAP_32B_REG(addr);
  67. cpu_physical_memory_write(addr, (void *) &value, 4);
  68. }
  69. /* MPU OS timers */
  70. struct omap_mpu_timer_s {
  71. MemoryRegion iomem;
  72. qemu_irq irq;
  73. omap_clk clk;
  74. uint32_t val;
  75. int64_t time;
  76. QEMUTimer *timer;
  77. QEMUBH *tick;
  78. int64_t rate;
  79. int it_ena;
  80. int enable;
  81. int ptv;
  82. int ar;
  83. int st;
  84. uint32_t reset_val;
  85. };
  86. static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
  87. {
  88. uint64_t distance = qemu_get_clock_ns(vm_clock) - timer->time;
  89. if (timer->st && timer->enable && timer->rate)
  90. return timer->val - muldiv64(distance >> (timer->ptv + 1),
  91. timer->rate, get_ticks_per_sec());
  92. else
  93. return timer->val;
  94. }
  95. static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
  96. {
  97. timer->val = omap_timer_read(timer);
  98. timer->time = qemu_get_clock_ns(vm_clock);
  99. }
  100. static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
  101. {
  102. int64_t expires;
  103. if (timer->enable && timer->st && timer->rate) {
  104. timer->val = timer->reset_val; /* Should skip this on clk enable */
  105. expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
  106. get_ticks_per_sec(), timer->rate);
  107. /* If timer expiry would be sooner than in about 1 ms and
  108. * auto-reload isn't set, then fire immediately. This is a hack
  109. * to make systems like PalmOS run in acceptable time. PalmOS
  110. * sets the interval to a very low value and polls the status bit
  111. * in a busy loop when it wants to sleep just a couple of CPU
  112. * ticks. */
  113. if (expires > (get_ticks_per_sec() >> 10) || timer->ar)
  114. qemu_mod_timer(timer->timer, timer->time + expires);
  115. else
  116. qemu_bh_schedule(timer->tick);
  117. } else
  118. qemu_del_timer(timer->timer);
  119. }
  120. static void omap_timer_fire(void *opaque)
  121. {
  122. struct omap_mpu_timer_s *timer = opaque;
  123. if (!timer->ar) {
  124. timer->val = 0;
  125. timer->st = 0;
  126. }
  127. if (timer->it_ena)
  128. /* Edge-triggered irq */
  129. qemu_irq_pulse(timer->irq);
  130. }
  131. static void omap_timer_tick(void *opaque)
  132. {
  133. struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
  134. omap_timer_sync(timer);
  135. omap_timer_fire(timer);
  136. omap_timer_update(timer);
  137. }
  138. static void omap_timer_clk_update(void *opaque, int line, int on)
  139. {
  140. struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
  141. omap_timer_sync(timer);
  142. timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
  143. omap_timer_update(timer);
  144. }
  145. static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
  146. {
  147. omap_clk_adduser(timer->clk,
  148. qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);
  149. timer->rate = omap_clk_getrate(timer->clk);
  150. }
  151. static uint64_t omap_mpu_timer_read(void *opaque, target_phys_addr_t addr,
  152. unsigned size)
  153. {
  154. struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
  155. if (size != 4) {
  156. return omap_badwidth_read32(opaque, addr);
  157. }
  158. switch (addr) {
  159. case 0x00: /* CNTL_TIMER */
  160. return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
  161. case 0x04: /* LOAD_TIM */
  162. break;
  163. case 0x08: /* READ_TIM */
  164. return omap_timer_read(s);
  165. }
  166. OMAP_BAD_REG(addr);
  167. return 0;
  168. }
  169. static void omap_mpu_timer_write(void *opaque, target_phys_addr_t addr,
  170. uint64_t value, unsigned size)
  171. {
  172. struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
  173. if (size != 4) {
  174. return omap_badwidth_write32(opaque, addr, value);
  175. }
  176. switch (addr) {
  177. case 0x00: /* CNTL_TIMER */
  178. omap_timer_sync(s);
  179. s->enable = (value >> 5) & 1;
  180. s->ptv = (value >> 2) & 7;
  181. s->ar = (value >> 1) & 1;
  182. s->st = value & 1;
  183. omap_timer_update(s);
  184. return;
  185. case 0x04: /* LOAD_TIM */
  186. s->reset_val = value;
  187. return;
  188. case 0x08: /* READ_TIM */
  189. OMAP_RO_REG(addr);
  190. break;
  191. default:
  192. OMAP_BAD_REG(addr);
  193. }
  194. }
  195. static const MemoryRegionOps omap_mpu_timer_ops = {
  196. .read = omap_mpu_timer_read,
  197. .write = omap_mpu_timer_write,
  198. .endianness = DEVICE_LITTLE_ENDIAN,
  199. };
  200. static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
  201. {
  202. qemu_del_timer(s->timer);
  203. s->enable = 0;
  204. s->reset_val = 31337;
  205. s->val = 0;
  206. s->ptv = 0;
  207. s->ar = 0;
  208. s->st = 0;
  209. s->it_ena = 1;
  210. }
  211. static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
  212. target_phys_addr_t base,
  213. qemu_irq irq, omap_clk clk)
  214. {
  215. struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
  216. g_malloc0(sizeof(struct omap_mpu_timer_s));
  217. s->irq = irq;
  218. s->clk = clk;
  219. s->timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, s);
  220. s->tick = qemu_bh_new(omap_timer_fire, s);
  221. omap_mpu_timer_reset(s);
  222. omap_timer_clk_setup(s);
  223. memory_region_init_io(&s->iomem, &omap_mpu_timer_ops, s,
  224. "omap-mpu-timer", 0x100);
  225. memory_region_add_subregion(system_memory, base, &s->iomem);
  226. return s;
  227. }
  228. /* Watchdog timer */
  229. struct omap_watchdog_timer_s {
  230. struct omap_mpu_timer_s timer;
  231. MemoryRegion iomem;
  232. uint8_t last_wr;
  233. int mode;
  234. int free;
  235. int reset;
  236. };
  237. static uint64_t omap_wd_timer_read(void *opaque, target_phys_addr_t addr,
  238. unsigned size)
  239. {
  240. struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
  241. if (size != 2) {
  242. return omap_badwidth_read16(opaque, addr);
  243. }
  244. switch (addr) {
  245. case 0x00: /* CNTL_TIMER */
  246. return (s->timer.ptv << 9) | (s->timer.ar << 8) |
  247. (s->timer.st << 7) | (s->free << 1);
  248. case 0x04: /* READ_TIMER */
  249. return omap_timer_read(&s->timer);
  250. case 0x08: /* TIMER_MODE */
  251. return s->mode << 15;
  252. }
  253. OMAP_BAD_REG(addr);
  254. return 0;
  255. }
  256. static void omap_wd_timer_write(void *opaque, target_phys_addr_t addr,
  257. uint64_t value, unsigned size)
  258. {
  259. struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
  260. if (size != 2) {
  261. return omap_badwidth_write16(opaque, addr, value);
  262. }
  263. switch (addr) {
  264. case 0x00: /* CNTL_TIMER */
  265. omap_timer_sync(&s->timer);
  266. s->timer.ptv = (value >> 9) & 7;
  267. s->timer.ar = (value >> 8) & 1;
  268. s->timer.st = (value >> 7) & 1;
  269. s->free = (value >> 1) & 1;
  270. omap_timer_update(&s->timer);
  271. break;
  272. case 0x04: /* LOAD_TIMER */
  273. s->timer.reset_val = value & 0xffff;
  274. break;
  275. case 0x08: /* TIMER_MODE */
  276. if (!s->mode && ((value >> 15) & 1))
  277. omap_clk_get(s->timer.clk);
  278. s->mode |= (value >> 15) & 1;
  279. if (s->last_wr == 0xf5) {
  280. if ((value & 0xff) == 0xa0) {
  281. if (s->mode) {
  282. s->mode = 0;
  283. omap_clk_put(s->timer.clk);
  284. }
  285. } else {
  286. /* XXX: on T|E hardware somehow this has no effect,
  287. * on Zire 71 it works as specified. */
  288. s->reset = 1;
  289. qemu_system_reset_request();
  290. }
  291. }
  292. s->last_wr = value & 0xff;
  293. break;
  294. default:
  295. OMAP_BAD_REG(addr);
  296. }
  297. }
  298. static const MemoryRegionOps omap_wd_timer_ops = {
  299. .read = omap_wd_timer_read,
  300. .write = omap_wd_timer_write,
  301. .endianness = DEVICE_NATIVE_ENDIAN,
  302. };
  303. static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
  304. {
  305. qemu_del_timer(s->timer.timer);
  306. if (!s->mode)
  307. omap_clk_get(s->timer.clk);
  308. s->mode = 1;
  309. s->free = 1;
  310. s->reset = 0;
  311. s->timer.enable = 1;
  312. s->timer.it_ena = 1;
  313. s->timer.reset_val = 0xffff;
  314. s->timer.val = 0;
  315. s->timer.st = 0;
  316. s->timer.ptv = 0;
  317. s->timer.ar = 0;
  318. omap_timer_update(&s->timer);
  319. }
  320. static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
  321. target_phys_addr_t base,
  322. qemu_irq irq, omap_clk clk)
  323. {
  324. struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
  325. g_malloc0(sizeof(struct omap_watchdog_timer_s));
  326. s->timer.irq = irq;
  327. s->timer.clk = clk;
  328. s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
  329. omap_wd_timer_reset(s);
  330. omap_timer_clk_setup(&s->timer);
  331. memory_region_init_io(&s->iomem, &omap_wd_timer_ops, s,
  332. "omap-wd-timer", 0x100);
  333. memory_region_add_subregion(memory, base, &s->iomem);
  334. return s;
  335. }
  336. /* 32-kHz timer */
  337. struct omap_32khz_timer_s {
  338. struct omap_mpu_timer_s timer;
  339. MemoryRegion iomem;
  340. };
  341. static uint64_t omap_os_timer_read(void *opaque, target_phys_addr_t addr,
  342. unsigned size)
  343. {
  344. struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
  345. int offset = addr & OMAP_MPUI_REG_MASK;
  346. if (size != 4) {
  347. return omap_badwidth_read32(opaque, addr);
  348. }
  349. switch (offset) {
  350. case 0x00: /* TVR */
  351. return s->timer.reset_val;
  352. case 0x04: /* TCR */
  353. return omap_timer_read(&s->timer);
  354. case 0x08: /* CR */
  355. return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
  356. default:
  357. break;
  358. }
  359. OMAP_BAD_REG(addr);
  360. return 0;
  361. }
  362. static void omap_os_timer_write(void *opaque, target_phys_addr_t addr,
  363. uint64_t value, unsigned size)
  364. {
  365. struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
  366. int offset = addr & OMAP_MPUI_REG_MASK;
  367. if (size != 4) {
  368. return omap_badwidth_write32(opaque, addr, value);
  369. }
  370. switch (offset) {
  371. case 0x00: /* TVR */
  372. s->timer.reset_val = value & 0x00ffffff;
  373. break;
  374. case 0x04: /* TCR */
  375. OMAP_RO_REG(addr);
  376. break;
  377. case 0x08: /* CR */
  378. s->timer.ar = (value >> 3) & 1;
  379. s->timer.it_ena = (value >> 2) & 1;
  380. if (s->timer.st != (value & 1) || (value & 2)) {
  381. omap_timer_sync(&s->timer);
  382. s->timer.enable = value & 1;
  383. s->timer.st = value & 1;
  384. omap_timer_update(&s->timer);
  385. }
  386. break;
  387. default:
  388. OMAP_BAD_REG(addr);
  389. }
  390. }
  391. static const MemoryRegionOps omap_os_timer_ops = {
  392. .read = omap_os_timer_read,
  393. .write = omap_os_timer_write,
  394. .endianness = DEVICE_NATIVE_ENDIAN,
  395. };
  396. static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
  397. {
  398. qemu_del_timer(s->timer.timer);
  399. s->timer.enable = 0;
  400. s->timer.it_ena = 0;
  401. s->timer.reset_val = 0x00ffffff;
  402. s->timer.val = 0;
  403. s->timer.st = 0;
  404. s->timer.ptv = 0;
  405. s->timer.ar = 1;
  406. }
  407. static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
  408. target_phys_addr_t base,
  409. qemu_irq irq, omap_clk clk)
  410. {
  411. struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
  412. g_malloc0(sizeof(struct omap_32khz_timer_s));
  413. s->timer.irq = irq;
  414. s->timer.clk = clk;
  415. s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
  416. omap_os_timer_reset(s);
  417. omap_timer_clk_setup(&s->timer);
  418. memory_region_init_io(&s->iomem, &omap_os_timer_ops, s,
  419. "omap-os-timer", 0x800);
  420. memory_region_add_subregion(memory, base, &s->iomem);
  421. return s;
  422. }
  423. /* Ultra Low-Power Device Module */
  424. static uint64_t omap_ulpd_pm_read(void *opaque, target_phys_addr_t addr,
  425. unsigned size)
  426. {
  427. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  428. uint16_t ret;
  429. if (size != 2) {
  430. return omap_badwidth_read16(opaque, addr);
  431. }
  432. switch (addr) {
  433. case 0x14: /* IT_STATUS */
  434. ret = s->ulpd_pm_regs[addr >> 2];
  435. s->ulpd_pm_regs[addr >> 2] = 0;
  436. qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
  437. return ret;
  438. case 0x18: /* Reserved */
  439. case 0x1c: /* Reserved */
  440. case 0x20: /* Reserved */
  441. case 0x28: /* Reserved */
  442. case 0x2c: /* Reserved */
  443. OMAP_BAD_REG(addr);
  444. case 0x00: /* COUNTER_32_LSB */
  445. case 0x04: /* COUNTER_32_MSB */
  446. case 0x08: /* COUNTER_HIGH_FREQ_LSB */
  447. case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
  448. case 0x10: /* GAUGING_CTRL */
  449. case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
  450. case 0x30: /* CLOCK_CTRL */
  451. case 0x34: /* SOFT_REQ */
  452. case 0x38: /* COUNTER_32_FIQ */
  453. case 0x3c: /* DPLL_CTRL */
  454. case 0x40: /* STATUS_REQ */
  455. /* XXX: check clk::usecount state for every clock */
  456. case 0x48: /* LOCL_TIME */
  457. case 0x4c: /* APLL_CTRL */
  458. case 0x50: /* POWER_CTRL */
  459. return s->ulpd_pm_regs[addr >> 2];
  460. }
  461. OMAP_BAD_REG(addr);
  462. return 0;
  463. }
  464. static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
  465. uint16_t diff, uint16_t value)
  466. {
  467. if (diff & (1 << 4)) /* USB_MCLK_EN */
  468. omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
  469. if (diff & (1 << 5)) /* DIS_USB_PVCI_CLK */
  470. omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
  471. }
  472. static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
  473. uint16_t diff, uint16_t value)
  474. {
  475. if (diff & (1 << 0)) /* SOFT_DPLL_REQ */
  476. omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
  477. if (diff & (1 << 1)) /* SOFT_COM_REQ */
  478. omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
  479. if (diff & (1 << 2)) /* SOFT_SDW_REQ */
  480. omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
  481. if (diff & (1 << 3)) /* SOFT_USB_REQ */
  482. omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
  483. }
  484. static void omap_ulpd_pm_write(void *opaque, target_phys_addr_t addr,
  485. uint64_t value, unsigned size)
  486. {
  487. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  488. int64_t now, ticks;
  489. int div, mult;
  490. static const int bypass_div[4] = { 1, 2, 4, 4 };
  491. uint16_t diff;
  492. if (size != 2) {
  493. return omap_badwidth_write16(opaque, addr, value);
  494. }
  495. switch (addr) {
  496. case 0x00: /* COUNTER_32_LSB */
  497. case 0x04: /* COUNTER_32_MSB */
  498. case 0x08: /* COUNTER_HIGH_FREQ_LSB */
  499. case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
  500. case 0x14: /* IT_STATUS */
  501. case 0x40: /* STATUS_REQ */
  502. OMAP_RO_REG(addr);
  503. break;
  504. case 0x10: /* GAUGING_CTRL */
  505. /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
  506. if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
  507. now = qemu_get_clock_ns(vm_clock);
  508. if (value & 1)
  509. s->ulpd_gauge_start = now;
  510. else {
  511. now -= s->ulpd_gauge_start;
  512. /* 32-kHz ticks */
  513. ticks = muldiv64(now, 32768, get_ticks_per_sec());
  514. s->ulpd_pm_regs[0x00 >> 2] = (ticks >> 0) & 0xffff;
  515. s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
  516. if (ticks >> 32) /* OVERFLOW_32K */
  517. s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
  518. /* High frequency ticks */
  519. ticks = muldiv64(now, 12000000, get_ticks_per_sec());
  520. s->ulpd_pm_regs[0x08 >> 2] = (ticks >> 0) & 0xffff;
  521. s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
  522. if (ticks >> 32) /* OVERFLOW_HI_FREQ */
  523. s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
  524. s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0; /* IT_GAUGING */
  525. qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
  526. }
  527. }
  528. s->ulpd_pm_regs[addr >> 2] = value;
  529. break;
  530. case 0x18: /* Reserved */
  531. case 0x1c: /* Reserved */
  532. case 0x20: /* Reserved */
  533. case 0x28: /* Reserved */
  534. case 0x2c: /* Reserved */
  535. OMAP_BAD_REG(addr);
  536. case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
  537. case 0x38: /* COUNTER_32_FIQ */
  538. case 0x48: /* LOCL_TIME */
  539. case 0x50: /* POWER_CTRL */
  540. s->ulpd_pm_regs[addr >> 2] = value;
  541. break;
  542. case 0x30: /* CLOCK_CTRL */
  543. diff = s->ulpd_pm_regs[addr >> 2] ^ value;
  544. s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
  545. omap_ulpd_clk_update(s, diff, value);
  546. break;
  547. case 0x34: /* SOFT_REQ */
  548. diff = s->ulpd_pm_regs[addr >> 2] ^ value;
  549. s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
  550. omap_ulpd_req_update(s, diff, value);
  551. break;
  552. case 0x3c: /* DPLL_CTRL */
  553. /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
  554. * omitted altogether, probably a typo. */
  555. /* This register has identical semantics with DPLL(1:3) control
  556. * registers, see omap_dpll_write() */
  557. diff = s->ulpd_pm_regs[addr >> 2] & value;
  558. s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
  559. if (diff & (0x3ff << 2)) {
  560. if (value & (1 << 4)) { /* PLL_ENABLE */
  561. div = ((value >> 5) & 3) + 1; /* PLL_DIV */
  562. mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */
  563. } else {
  564. div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */
  565. mult = 1;
  566. }
  567. omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
  568. }
  569. /* Enter the desired mode. */
  570. s->ulpd_pm_regs[addr >> 2] =
  571. (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
  572. ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
  573. /* Act as if the lock is restored. */
  574. s->ulpd_pm_regs[addr >> 2] |= 2;
  575. break;
  576. case 0x4c: /* APLL_CTRL */
  577. diff = s->ulpd_pm_regs[addr >> 2] & value;
  578. s->ulpd_pm_regs[addr >> 2] = value & 0xf;
  579. if (diff & (1 << 0)) /* APLL_NDPLL_SWITCH */
  580. omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
  581. (value & (1 << 0)) ? "apll" : "dpll4"));
  582. break;
  583. default:
  584. OMAP_BAD_REG(addr);
  585. }
  586. }
  587. static const MemoryRegionOps omap_ulpd_pm_ops = {
  588. .read = omap_ulpd_pm_read,
  589. .write = omap_ulpd_pm_write,
  590. .endianness = DEVICE_NATIVE_ENDIAN,
  591. };
  592. static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
  593. {
  594. mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
  595. mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
  596. mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
  597. mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
  598. mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
  599. mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
  600. mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
  601. mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
  602. mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
  603. mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
  604. mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
  605. omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
  606. mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
  607. omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
  608. mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
  609. mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
  610. mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
  611. mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
  612. mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
  613. mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
  614. mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
  615. omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
  616. omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
  617. }
  618. static void omap_ulpd_pm_init(MemoryRegion *system_memory,
  619. target_phys_addr_t base,
  620. struct omap_mpu_state_s *mpu)
  621. {
  622. memory_region_init_io(&mpu->ulpd_pm_iomem, &omap_ulpd_pm_ops, mpu,
  623. "omap-ulpd-pm", 0x800);
  624. memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
  625. omap_ulpd_pm_reset(mpu);
  626. }
  627. /* OMAP Pin Configuration */
  628. static uint64_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr,
  629. unsigned size)
  630. {
  631. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  632. if (size != 4) {
  633. return omap_badwidth_read32(opaque, addr);
  634. }
  635. switch (addr) {
  636. case 0x00: /* FUNC_MUX_CTRL_0 */
  637. case 0x04: /* FUNC_MUX_CTRL_1 */
  638. case 0x08: /* FUNC_MUX_CTRL_2 */
  639. return s->func_mux_ctrl[addr >> 2];
  640. case 0x0c: /* COMP_MODE_CTRL_0 */
  641. return s->comp_mode_ctrl[0];
  642. case 0x10: /* FUNC_MUX_CTRL_3 */
  643. case 0x14: /* FUNC_MUX_CTRL_4 */
  644. case 0x18: /* FUNC_MUX_CTRL_5 */
  645. case 0x1c: /* FUNC_MUX_CTRL_6 */
  646. case 0x20: /* FUNC_MUX_CTRL_7 */
  647. case 0x24: /* FUNC_MUX_CTRL_8 */
  648. case 0x28: /* FUNC_MUX_CTRL_9 */
  649. case 0x2c: /* FUNC_MUX_CTRL_A */
  650. case 0x30: /* FUNC_MUX_CTRL_B */
  651. case 0x34: /* FUNC_MUX_CTRL_C */
  652. case 0x38: /* FUNC_MUX_CTRL_D */
  653. return s->func_mux_ctrl[(addr >> 2) - 1];
  654. case 0x40: /* PULL_DWN_CTRL_0 */
  655. case 0x44: /* PULL_DWN_CTRL_1 */
  656. case 0x48: /* PULL_DWN_CTRL_2 */
  657. case 0x4c: /* PULL_DWN_CTRL_3 */
  658. return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
  659. case 0x50: /* GATE_INH_CTRL_0 */
  660. return s->gate_inh_ctrl[0];
  661. case 0x60: /* VOLTAGE_CTRL_0 */
  662. return s->voltage_ctrl[0];
  663. case 0x70: /* TEST_DBG_CTRL_0 */
  664. return s->test_dbg_ctrl[0];
  665. case 0x80: /* MOD_CONF_CTRL_0 */
  666. return s->mod_conf_ctrl[0];
  667. }
  668. OMAP_BAD_REG(addr);
  669. return 0;
  670. }
  671. static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
  672. uint32_t diff, uint32_t value)
  673. {
  674. if (s->compat1509) {
  675. if (diff & (1 << 9)) /* BLUETOOTH */
  676. omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
  677. (~value >> 9) & 1);
  678. if (diff & (1 << 7)) /* USB.CLKO */
  679. omap_clk_onoff(omap_findclk(s, "usb.clko"),
  680. (value >> 7) & 1);
  681. }
  682. }
  683. static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
  684. uint32_t diff, uint32_t value)
  685. {
  686. if (s->compat1509) {
  687. if (diff & (1 << 31)) /* MCBSP3_CLK_HIZ_DI */
  688. omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"),
  689. (value >> 31) & 1);
  690. if (diff & (1 << 1)) /* CLK32K */
  691. omap_clk_onoff(omap_findclk(s, "clk32k_out"),
  692. (~value >> 1) & 1);
  693. }
  694. }
  695. static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
  696. uint32_t diff, uint32_t value)
  697. {
  698. if (diff & (1 << 31)) /* CONF_MOD_UART3_CLK_MODE_R */
  699. omap_clk_reparent(omap_findclk(s, "uart3_ck"),
  700. omap_findclk(s, ((value >> 31) & 1) ?
  701. "ck_48m" : "armper_ck"));
  702. if (diff & (1 << 30)) /* CONF_MOD_UART2_CLK_MODE_R */
  703. omap_clk_reparent(omap_findclk(s, "uart2_ck"),
  704. omap_findclk(s, ((value >> 30) & 1) ?
  705. "ck_48m" : "armper_ck"));
  706. if (diff & (1 << 29)) /* CONF_MOD_UART1_CLK_MODE_R */
  707. omap_clk_reparent(omap_findclk(s, "uart1_ck"),
  708. omap_findclk(s, ((value >> 29) & 1) ?
  709. "ck_48m" : "armper_ck"));
  710. if (diff & (1 << 23)) /* CONF_MOD_MMC_SD_CLK_REQ_R */
  711. omap_clk_reparent(omap_findclk(s, "mmc_ck"),
  712. omap_findclk(s, ((value >> 23) & 1) ?
  713. "ck_48m" : "armper_ck"));
  714. if (diff & (1 << 12)) /* CONF_MOD_COM_MCLK_12_48_S */
  715. omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
  716. omap_findclk(s, ((value >> 12) & 1) ?
  717. "ck_48m" : "armper_ck"));
  718. if (diff & (1 << 9)) /* CONF_MOD_USB_HOST_HHC_UHO */
  719. omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
  720. }
  721. static void omap_pin_cfg_write(void *opaque, target_phys_addr_t addr,
  722. uint64_t value, unsigned size)
  723. {
  724. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  725. uint32_t diff;
  726. if (size != 4) {
  727. return omap_badwidth_write32(opaque, addr, value);
  728. }
  729. switch (addr) {
  730. case 0x00: /* FUNC_MUX_CTRL_0 */
  731. diff = s->func_mux_ctrl[addr >> 2] ^ value;
  732. s->func_mux_ctrl[addr >> 2] = value;
  733. omap_pin_funcmux0_update(s, diff, value);
  734. return;
  735. case 0x04: /* FUNC_MUX_CTRL_1 */
  736. diff = s->func_mux_ctrl[addr >> 2] ^ value;
  737. s->func_mux_ctrl[addr >> 2] = value;
  738. omap_pin_funcmux1_update(s, diff, value);
  739. return;
  740. case 0x08: /* FUNC_MUX_CTRL_2 */
  741. s->func_mux_ctrl[addr >> 2] = value;
  742. return;
  743. case 0x0c: /* COMP_MODE_CTRL_0 */
  744. s->comp_mode_ctrl[0] = value;
  745. s->compat1509 = (value != 0x0000eaef);
  746. omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
  747. omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
  748. return;
  749. case 0x10: /* FUNC_MUX_CTRL_3 */
  750. case 0x14: /* FUNC_MUX_CTRL_4 */
  751. case 0x18: /* FUNC_MUX_CTRL_5 */
  752. case 0x1c: /* FUNC_MUX_CTRL_6 */
  753. case 0x20: /* FUNC_MUX_CTRL_7 */
  754. case 0x24: /* FUNC_MUX_CTRL_8 */
  755. case 0x28: /* FUNC_MUX_CTRL_9 */
  756. case 0x2c: /* FUNC_MUX_CTRL_A */
  757. case 0x30: /* FUNC_MUX_CTRL_B */
  758. case 0x34: /* FUNC_MUX_CTRL_C */
  759. case 0x38: /* FUNC_MUX_CTRL_D */
  760. s->func_mux_ctrl[(addr >> 2) - 1] = value;
  761. return;
  762. case 0x40: /* PULL_DWN_CTRL_0 */
  763. case 0x44: /* PULL_DWN_CTRL_1 */
  764. case 0x48: /* PULL_DWN_CTRL_2 */
  765. case 0x4c: /* PULL_DWN_CTRL_3 */
  766. s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
  767. return;
  768. case 0x50: /* GATE_INH_CTRL_0 */
  769. s->gate_inh_ctrl[0] = value;
  770. return;
  771. case 0x60: /* VOLTAGE_CTRL_0 */
  772. s->voltage_ctrl[0] = value;
  773. return;
  774. case 0x70: /* TEST_DBG_CTRL_0 */
  775. s->test_dbg_ctrl[0] = value;
  776. return;
  777. case 0x80: /* MOD_CONF_CTRL_0 */
  778. diff = s->mod_conf_ctrl[0] ^ value;
  779. s->mod_conf_ctrl[0] = value;
  780. omap_pin_modconf1_update(s, diff, value);
  781. return;
  782. default:
  783. OMAP_BAD_REG(addr);
  784. }
  785. }
  786. static const MemoryRegionOps omap_pin_cfg_ops = {
  787. .read = omap_pin_cfg_read,
  788. .write = omap_pin_cfg_write,
  789. .endianness = DEVICE_NATIVE_ENDIAN,
  790. };
  791. static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
  792. {
  793. /* Start in Compatibility Mode. */
  794. mpu->compat1509 = 1;
  795. omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
  796. omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
  797. omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
  798. memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
  799. memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
  800. memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
  801. memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
  802. memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
  803. memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
  804. memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
  805. }
  806. static void omap_pin_cfg_init(MemoryRegion *system_memory,
  807. target_phys_addr_t base,
  808. struct omap_mpu_state_s *mpu)
  809. {
  810. memory_region_init_io(&mpu->pin_cfg_iomem, &omap_pin_cfg_ops, mpu,
  811. "omap-pin-cfg", 0x800);
  812. memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
  813. omap_pin_cfg_reset(mpu);
  814. }
  815. /* Device Identification, Die Identification */
  816. static uint64_t omap_id_read(void *opaque, target_phys_addr_t addr,
  817. unsigned size)
  818. {
  819. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  820. if (size != 4) {
  821. return omap_badwidth_read32(opaque, addr);
  822. }
  823. switch (addr) {
  824. case 0xfffe1800: /* DIE_ID_LSB */
  825. return 0xc9581f0e;
  826. case 0xfffe1804: /* DIE_ID_MSB */
  827. return 0xa8858bfa;
  828. case 0xfffe2000: /* PRODUCT_ID_LSB */
  829. return 0x00aaaafc;
  830. case 0xfffe2004: /* PRODUCT_ID_MSB */
  831. return 0xcafeb574;
  832. case 0xfffed400: /* JTAG_ID_LSB */
  833. switch (s->mpu_model) {
  834. case omap310:
  835. return 0x03310315;
  836. case omap1510:
  837. return 0x03310115;
  838. default:
  839. hw_error("%s: bad mpu model\n", __FUNCTION__);
  840. }
  841. break;
  842. case 0xfffed404: /* JTAG_ID_MSB */
  843. switch (s->mpu_model) {
  844. case omap310:
  845. return 0xfb57402f;
  846. case omap1510:
  847. return 0xfb47002f;
  848. default:
  849. hw_error("%s: bad mpu model\n", __FUNCTION__);
  850. }
  851. break;
  852. }
  853. OMAP_BAD_REG(addr);
  854. return 0;
  855. }
  856. static void omap_id_write(void *opaque, target_phys_addr_t addr,
  857. uint64_t value, unsigned size)
  858. {
  859. if (size != 4) {
  860. return omap_badwidth_write32(opaque, addr, value);
  861. }
  862. OMAP_BAD_REG(addr);
  863. }
  864. static const MemoryRegionOps omap_id_ops = {
  865. .read = omap_id_read,
  866. .write = omap_id_write,
  867. .endianness = DEVICE_NATIVE_ENDIAN,
  868. };
  869. static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
  870. {
  871. memory_region_init_io(&mpu->id_iomem, &omap_id_ops, mpu,
  872. "omap-id", 0x100000000ULL);
  873. memory_region_init_alias(&mpu->id_iomem_e18, "omap-id-e18", &mpu->id_iomem,
  874. 0xfffe1800, 0x800);
  875. memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
  876. memory_region_init_alias(&mpu->id_iomem_ed4, "omap-id-ed4", &mpu->id_iomem,
  877. 0xfffed400, 0x100);
  878. memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
  879. if (!cpu_is_omap15xx(mpu)) {
  880. memory_region_init_alias(&mpu->id_iomem_ed4, "omap-id-e20",
  881. &mpu->id_iomem, 0xfffe2000, 0x800);
  882. memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
  883. }
  884. }
  885. /* MPUI Control (Dummy) */
  886. static uint64_t omap_mpui_read(void *opaque, target_phys_addr_t addr,
  887. unsigned size)
  888. {
  889. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  890. if (size != 4) {
  891. return omap_badwidth_read32(opaque, addr);
  892. }
  893. switch (addr) {
  894. case 0x00: /* CTRL */
  895. return s->mpui_ctrl;
  896. case 0x04: /* DEBUG_ADDR */
  897. return 0x01ffffff;
  898. case 0x08: /* DEBUG_DATA */
  899. return 0xffffffff;
  900. case 0x0c: /* DEBUG_FLAG */
  901. return 0x00000800;
  902. case 0x10: /* STATUS */
  903. return 0x00000000;
  904. /* Not in OMAP310 */
  905. case 0x14: /* DSP_STATUS */
  906. case 0x18: /* DSP_BOOT_CONFIG */
  907. return 0x00000000;
  908. case 0x1c: /* DSP_MPUI_CONFIG */
  909. return 0x0000ffff;
  910. }
  911. OMAP_BAD_REG(addr);
  912. return 0;
  913. }
  914. static void omap_mpui_write(void *opaque, target_phys_addr_t addr,
  915. uint64_t value, unsigned size)
  916. {
  917. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  918. if (size != 4) {
  919. return omap_badwidth_write32(opaque, addr, value);
  920. }
  921. switch (addr) {
  922. case 0x00: /* CTRL */
  923. s->mpui_ctrl = value & 0x007fffff;
  924. break;
  925. case 0x04: /* DEBUG_ADDR */
  926. case 0x08: /* DEBUG_DATA */
  927. case 0x0c: /* DEBUG_FLAG */
  928. case 0x10: /* STATUS */
  929. /* Not in OMAP310 */
  930. case 0x14: /* DSP_STATUS */
  931. OMAP_RO_REG(addr);
  932. case 0x18: /* DSP_BOOT_CONFIG */
  933. case 0x1c: /* DSP_MPUI_CONFIG */
  934. break;
  935. default:
  936. OMAP_BAD_REG(addr);
  937. }
  938. }
  939. static const MemoryRegionOps omap_mpui_ops = {
  940. .read = omap_mpui_read,
  941. .write = omap_mpui_write,
  942. .endianness = DEVICE_NATIVE_ENDIAN,
  943. };
  944. static void omap_mpui_reset(struct omap_mpu_state_s *s)
  945. {
  946. s->mpui_ctrl = 0x0003ff1b;
  947. }
  948. static void omap_mpui_init(MemoryRegion *memory, target_phys_addr_t base,
  949. struct omap_mpu_state_s *mpu)
  950. {
  951. memory_region_init_io(&mpu->mpui_iomem, &omap_mpui_ops, mpu,
  952. "omap-mpui", 0x100);
  953. memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
  954. omap_mpui_reset(mpu);
  955. }
  956. /* TIPB Bridges */
  957. struct omap_tipb_bridge_s {
  958. qemu_irq abort;
  959. MemoryRegion iomem;
  960. int width_intr;
  961. uint16_t control;
  962. uint16_t alloc;
  963. uint16_t buffer;
  964. uint16_t enh_control;
  965. };
  966. static uint64_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr,
  967. unsigned size)
  968. {
  969. struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
  970. if (size < 2) {
  971. return omap_badwidth_read16(opaque, addr);
  972. }
  973. switch (addr) {
  974. case 0x00: /* TIPB_CNTL */
  975. return s->control;
  976. case 0x04: /* TIPB_BUS_ALLOC */
  977. return s->alloc;
  978. case 0x08: /* MPU_TIPB_CNTL */
  979. return s->buffer;
  980. case 0x0c: /* ENHANCED_TIPB_CNTL */
  981. return s->enh_control;
  982. case 0x10: /* ADDRESS_DBG */
  983. case 0x14: /* DATA_DEBUG_LOW */
  984. case 0x18: /* DATA_DEBUG_HIGH */
  985. return 0xffff;
  986. case 0x1c: /* DEBUG_CNTR_SIG */
  987. return 0x00f8;
  988. }
  989. OMAP_BAD_REG(addr);
  990. return 0;
  991. }
  992. static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,
  993. uint64_t value, unsigned size)
  994. {
  995. struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
  996. if (size < 2) {
  997. return omap_badwidth_write16(opaque, addr, value);
  998. }
  999. switch (addr) {
  1000. case 0x00: /* TIPB_CNTL */
  1001. s->control = value & 0xffff;
  1002. break;
  1003. case 0x04: /* TIPB_BUS_ALLOC */
  1004. s->alloc = value & 0x003f;
  1005. break;
  1006. case 0x08: /* MPU_TIPB_CNTL */
  1007. s->buffer = value & 0x0003;
  1008. break;
  1009. case 0x0c: /* ENHANCED_TIPB_CNTL */
  1010. s->width_intr = !(value & 2);
  1011. s->enh_control = value & 0x000f;
  1012. break;
  1013. case 0x10: /* ADDRESS_DBG */
  1014. case 0x14: /* DATA_DEBUG_LOW */
  1015. case 0x18: /* DATA_DEBUG_HIGH */
  1016. case 0x1c: /* DEBUG_CNTR_SIG */
  1017. OMAP_RO_REG(addr);
  1018. break;
  1019. default:
  1020. OMAP_BAD_REG(addr);
  1021. }
  1022. }
  1023. static const MemoryRegionOps omap_tipb_bridge_ops = {
  1024. .read = omap_tipb_bridge_read,
  1025. .write = omap_tipb_bridge_write,
  1026. .endianness = DEVICE_NATIVE_ENDIAN,
  1027. };
  1028. static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
  1029. {
  1030. s->control = 0xffff;
  1031. s->alloc = 0x0009;
  1032. s->buffer = 0x0000;
  1033. s->enh_control = 0x000f;
  1034. }
  1035. static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
  1036. MemoryRegion *memory, target_phys_addr_t base,
  1037. qemu_irq abort_irq, omap_clk clk)
  1038. {
  1039. struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
  1040. g_malloc0(sizeof(struct omap_tipb_bridge_s));
  1041. s->abort = abort_irq;
  1042. omap_tipb_bridge_reset(s);
  1043. memory_region_init_io(&s->iomem, &omap_tipb_bridge_ops, s,
  1044. "omap-tipb-bridge", 0x100);
  1045. memory_region_add_subregion(memory, base, &s->iomem);
  1046. return s;
  1047. }
  1048. /* Dummy Traffic Controller's Memory Interface */
  1049. static uint64_t omap_tcmi_read(void *opaque, target_phys_addr_t addr,
  1050. unsigned size)
  1051. {
  1052. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  1053. uint32_t ret;
  1054. if (size != 4) {
  1055. return omap_badwidth_read32(opaque, addr);
  1056. }
  1057. switch (addr) {
  1058. case 0x00: /* IMIF_PRIO */
  1059. case 0x04: /* EMIFS_PRIO */
  1060. case 0x08: /* EMIFF_PRIO */
  1061. case 0x0c: /* EMIFS_CONFIG */
  1062. case 0x10: /* EMIFS_CS0_CONFIG */
  1063. case 0x14: /* EMIFS_CS1_CONFIG */
  1064. case 0x18: /* EMIFS_CS2_CONFIG */
  1065. case 0x1c: /* EMIFS_CS3_CONFIG */
  1066. case 0x24: /* EMIFF_MRS */
  1067. case 0x28: /* TIMEOUT1 */
  1068. case 0x2c: /* TIMEOUT2 */
  1069. case 0x30: /* TIMEOUT3 */
  1070. case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
  1071. case 0x40: /* EMIFS_CFG_DYN_WAIT */
  1072. return s->tcmi_regs[addr >> 2];
  1073. case 0x20: /* EMIFF_SDRAM_CONFIG */
  1074. ret = s->tcmi_regs[addr >> 2];
  1075. s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
  1076. /* XXX: We can try using the VGA_DIRTY flag for this */
  1077. return ret;
  1078. }
  1079. OMAP_BAD_REG(addr);
  1080. return 0;
  1081. }
  1082. static void omap_tcmi_write(void *opaque, target_phys_addr_t addr,
  1083. uint64_t value, unsigned size)
  1084. {
  1085. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  1086. if (size != 4) {
  1087. return omap_badwidth_write32(opaque, addr, value);
  1088. }
  1089. switch (addr) {
  1090. case 0x00: /* IMIF_PRIO */
  1091. case 0x04: /* EMIFS_PRIO */
  1092. case 0x08: /* EMIFF_PRIO */
  1093. case 0x10: /* EMIFS_CS0_CONFIG */
  1094. case 0x14: /* EMIFS_CS1_CONFIG */
  1095. case 0x18: /* EMIFS_CS2_CONFIG */
  1096. case 0x1c: /* EMIFS_CS3_CONFIG */
  1097. case 0x20: /* EMIFF_SDRAM_CONFIG */
  1098. case 0x24: /* EMIFF_MRS */
  1099. case 0x28: /* TIMEOUT1 */
  1100. case 0x2c: /* TIMEOUT2 */
  1101. case 0x30: /* TIMEOUT3 */
  1102. case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
  1103. case 0x40: /* EMIFS_CFG_DYN_WAIT */
  1104. s->tcmi_regs[addr >> 2] = value;
  1105. break;
  1106. case 0x0c: /* EMIFS_CONFIG */
  1107. s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
  1108. break;
  1109. default:
  1110. OMAP_BAD_REG(addr);
  1111. }
  1112. }
  1113. static const MemoryRegionOps omap_tcmi_ops = {
  1114. .read = omap_tcmi_read,
  1115. .write = omap_tcmi_write,
  1116. .endianness = DEVICE_NATIVE_ENDIAN,
  1117. };
  1118. static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
  1119. {
  1120. mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
  1121. mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
  1122. mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
  1123. mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
  1124. mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
  1125. mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
  1126. mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
  1127. mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
  1128. mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
  1129. mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
  1130. mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
  1131. mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
  1132. mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
  1133. mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
  1134. mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
  1135. }
  1136. static void omap_tcmi_init(MemoryRegion *memory, target_phys_addr_t base,
  1137. struct omap_mpu_state_s *mpu)
  1138. {
  1139. memory_region_init_io(&mpu->tcmi_iomem, &omap_tcmi_ops, mpu,
  1140. "omap-tcmi", 0x100);
  1141. memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
  1142. omap_tcmi_reset(mpu);
  1143. }
  1144. /* Digital phase-locked loops control */
  1145. struct dpll_ctl_s {
  1146. MemoryRegion iomem;
  1147. uint16_t mode;
  1148. omap_clk dpll;
  1149. };
  1150. static uint64_t omap_dpll_read(void *opaque, target_phys_addr_t addr,
  1151. unsigned size)
  1152. {
  1153. struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
  1154. if (size != 2) {
  1155. return omap_badwidth_read16(opaque, addr);
  1156. }
  1157. if (addr == 0x00) /* CTL_REG */
  1158. return s->mode;
  1159. OMAP_BAD_REG(addr);
  1160. return 0;
  1161. }
  1162. static void omap_dpll_write(void *opaque, target_phys_addr_t addr,
  1163. uint64_t value, unsigned size)
  1164. {
  1165. struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
  1166. uint16_t diff;
  1167. static const int bypass_div[4] = { 1, 2, 4, 4 };
  1168. int div, mult;
  1169. if (size != 2) {
  1170. return omap_badwidth_write16(opaque, addr, value);
  1171. }
  1172. if (addr == 0x00) { /* CTL_REG */
  1173. /* See omap_ulpd_pm_write() too */
  1174. diff = s->mode & value;
  1175. s->mode = value & 0x2fff;
  1176. if (diff & (0x3ff << 2)) {
  1177. if (value & (1 << 4)) { /* PLL_ENABLE */
  1178. div = ((value >> 5) & 3) + 1; /* PLL_DIV */
  1179. mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */
  1180. } else {
  1181. div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */
  1182. mult = 1;
  1183. }
  1184. omap_clk_setrate(s->dpll, div, mult);
  1185. }
  1186. /* Enter the desired mode. */
  1187. s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
  1188. /* Act as if the lock is restored. */
  1189. s->mode |= 2;
  1190. } else {
  1191. OMAP_BAD_REG(addr);
  1192. }
  1193. }
  1194. static const MemoryRegionOps omap_dpll_ops = {
  1195. .read = omap_dpll_read,
  1196. .write = omap_dpll_write,
  1197. .endianness = DEVICE_NATIVE_ENDIAN,
  1198. };
  1199. static void omap_dpll_reset(struct dpll_ctl_s *s)
  1200. {
  1201. s->mode = 0x2002;
  1202. omap_clk_setrate(s->dpll, 1, 1);
  1203. }
  1204. static struct dpll_ctl_s *omap_dpll_init(MemoryRegion *memory,
  1205. target_phys_addr_t base, omap_clk clk)
  1206. {
  1207. struct dpll_ctl_s *s = g_malloc0(sizeof(*s));
  1208. memory_region_init_io(&s->iomem, &omap_dpll_ops, s, "omap-dpll", 0x100);
  1209. s->dpll = clk;
  1210. omap_dpll_reset(s);
  1211. memory_region_add_subregion(memory, base, &s->iomem);
  1212. return s;
  1213. }
  1214. /* MPU Clock/Reset/Power Mode Control */
  1215. static uint64_t omap_clkm_read(void *opaque, target_phys_addr_t addr,
  1216. unsigned size)
  1217. {
  1218. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  1219. if (size != 2) {
  1220. return omap_badwidth_read16(opaque, addr);
  1221. }
  1222. switch (addr) {
  1223. case 0x00: /* ARM_CKCTL */
  1224. return s->clkm.arm_ckctl;
  1225. case 0x04: /* ARM_IDLECT1 */
  1226. return s->clkm.arm_idlect1;
  1227. case 0x08: /* ARM_IDLECT2 */
  1228. return s->clkm.arm_idlect2;
  1229. case 0x0c: /* ARM_EWUPCT */
  1230. return s->clkm.arm_ewupct;
  1231. case 0x10: /* ARM_RSTCT1 */
  1232. return s->clkm.arm_rstct1;
  1233. case 0x14: /* ARM_RSTCT2 */
  1234. return s->clkm.arm_rstct2;
  1235. case 0x18: /* ARM_SYSST */
  1236. return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
  1237. case 0x1c: /* ARM_CKOUT1 */
  1238. return s->clkm.arm_ckout1;
  1239. case 0x20: /* ARM_CKOUT2 */
  1240. break;
  1241. }
  1242. OMAP_BAD_REG(addr);
  1243. return 0;
  1244. }
  1245. static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
  1246. uint16_t diff, uint16_t value)
  1247. {
  1248. omap_clk clk;
  1249. if (diff & (1 << 14)) { /* ARM_INTHCK_SEL */
  1250. if (value & (1 << 14))
  1251. /* Reserved */;
  1252. else {
  1253. clk = omap_findclk(s, "arminth_ck");
  1254. omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
  1255. }
  1256. }
  1257. if (diff & (1 << 12)) { /* ARM_TIMXO */
  1258. clk = omap_findclk(s, "armtim_ck");
  1259. if (value & (1 << 12))
  1260. omap_clk_reparent(clk, omap_findclk(s, "clkin"));
  1261. else
  1262. omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
  1263. }
  1264. /* XXX: en_dspck */
  1265. if (diff & (3 << 10)) { /* DSPMMUDIV */
  1266. clk = omap_findclk(s, "dspmmu_ck");
  1267. omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
  1268. }
  1269. if (diff & (3 << 8)) { /* TCDIV */
  1270. clk = omap_findclk(s, "tc_ck");
  1271. omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
  1272. }
  1273. if (diff & (3 << 6)) { /* DSPDIV */
  1274. clk = omap_findclk(s, "dsp_ck");
  1275. omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
  1276. }
  1277. if (diff & (3 << 4)) { /* ARMDIV */
  1278. clk = omap_findclk(s, "arm_ck");
  1279. omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
  1280. }
  1281. if (diff & (3 << 2)) { /* LCDDIV */
  1282. clk = omap_findclk(s, "lcd_ck");
  1283. omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
  1284. }
  1285. if (diff & (3 << 0)) { /* PERDIV */
  1286. clk = omap_findclk(s, "armper_ck");
  1287. omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
  1288. }
  1289. }
  1290. static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
  1291. uint16_t diff, uint16_t value)
  1292. {
  1293. omap_clk clk;
  1294. if (value & (1 << 11)) { /* SETARM_IDLE */
  1295. cpu_interrupt(&s->cpu->env, CPU_INTERRUPT_HALT);
  1296. }
  1297. if (!(value & (1 << 10))) /* WKUP_MODE */
  1298. qemu_system_shutdown_request(); /* XXX: disable wakeup from IRQ */
  1299. #define SET_CANIDLE(clock, bit) \
  1300. if (diff & (1 << bit)) { \
  1301. clk = omap_findclk(s, clock); \
  1302. omap_clk_canidle(clk, (value >> bit) & 1); \
  1303. }
  1304. SET_CANIDLE("mpuwd_ck", 0) /* IDLWDT_ARM */
  1305. SET_CANIDLE("armxor_ck", 1) /* IDLXORP_ARM */
  1306. SET_CANIDLE("mpuper_ck", 2) /* IDLPER_ARM */
  1307. SET_CANIDLE("lcd_ck", 3) /* IDLLCD_ARM */
  1308. SET_CANIDLE("lb_ck", 4) /* IDLLB_ARM */
  1309. SET_CANIDLE("hsab_ck", 5) /* IDLHSAB_ARM */
  1310. SET_CANIDLE("tipb_ck", 6) /* IDLIF_ARM */
  1311. SET_CANIDLE("dma_ck", 6) /* IDLIF_ARM */
  1312. SET_CANIDLE("tc_ck", 6) /* IDLIF_ARM */
  1313. SET_CANIDLE("dpll1", 7) /* IDLDPLL_ARM */
  1314. SET_CANIDLE("dpll2", 7) /* IDLDPLL_ARM */
  1315. SET_CANIDLE("dpll3", 7) /* IDLDPLL_ARM */
  1316. SET_CANIDLE("mpui_ck", 8) /* IDLAPI_ARM */
  1317. SET_CANIDLE("armtim_ck", 9) /* IDLTIM_ARM */
  1318. }
  1319. static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
  1320. uint16_t diff, uint16_t value)
  1321. {
  1322. omap_clk clk;
  1323. #define SET_ONOFF(clock, bit) \
  1324. if (diff & (1 << bit)) { \
  1325. clk = omap_findclk(s, clock); \
  1326. omap_clk_onoff(clk, (value >> bit) & 1); \
  1327. }
  1328. SET_ONOFF("mpuwd_ck", 0) /* EN_WDTCK */
  1329. SET_ONOFF("armxor_ck", 1) /* EN_XORPCK */
  1330. SET_ONOFF("mpuper_ck", 2) /* EN_PERCK */
  1331. SET_ONOFF("lcd_ck", 3) /* EN_LCDCK */
  1332. SET_ONOFF("lb_ck", 4) /* EN_LBCK */
  1333. SET_ONOFF("hsab_ck", 5) /* EN_HSABCK */
  1334. SET_ONOFF("mpui_ck", 6) /* EN_APICK */
  1335. SET_ONOFF("armtim_ck", 7) /* EN_TIMCK */
  1336. SET_CANIDLE("dma_ck", 8) /* DMACK_REQ */
  1337. SET_ONOFF("arm_gpio_ck", 9) /* EN_GPIOCK */
  1338. SET_ONOFF("lbfree_ck", 10) /* EN_LBFREECK */
  1339. }
  1340. static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
  1341. uint16_t diff, uint16_t value)
  1342. {
  1343. omap_clk clk;
  1344. if (diff & (3 << 4)) { /* TCLKOUT */
  1345. clk = omap_findclk(s, "tclk_out");
  1346. switch ((value >> 4) & 3) {
  1347. case 1:
  1348. omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
  1349. omap_clk_onoff(clk, 1);
  1350. break;
  1351. case 2:
  1352. omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
  1353. omap_clk_onoff(clk, 1);
  1354. break;
  1355. default:
  1356. omap_clk_onoff(clk, 0);
  1357. }
  1358. }
  1359. if (diff & (3 << 2)) { /* DCLKOUT */
  1360. clk = omap_findclk(s, "dclk_out");
  1361. switch ((value >> 2) & 3) {
  1362. case 0:
  1363. omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
  1364. break;
  1365. case 1:
  1366. omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
  1367. break;
  1368. case 2:
  1369. omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
  1370. break;
  1371. case 3:
  1372. omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
  1373. break;
  1374. }
  1375. }
  1376. if (diff & (3 << 0)) { /* ACLKOUT */
  1377. clk = omap_findclk(s, "aclk_out");
  1378. switch ((value >> 0) & 3) {
  1379. case 1:
  1380. omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
  1381. omap_clk_onoff(clk, 1);
  1382. break;
  1383. case 2:
  1384. omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
  1385. omap_clk_onoff(clk, 1);
  1386. break;
  1387. case 3:
  1388. omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
  1389. omap_clk_onoff(clk, 1);
  1390. break;
  1391. default:
  1392. omap_clk_onoff(clk, 0);
  1393. }
  1394. }
  1395. }
  1396. static void omap_clkm_write(void *opaque, target_phys_addr_t addr,
  1397. uint64_t value, unsigned size)
  1398. {
  1399. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  1400. uint16_t diff;
  1401. omap_clk clk;
  1402. static const char *clkschemename[8] = {
  1403. "fully synchronous", "fully asynchronous", "synchronous scalable",
  1404. "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
  1405. };
  1406. if (size != 2) {
  1407. return omap_badwidth_write16(opaque, addr, value);
  1408. }
  1409. switch (addr) {
  1410. case 0x00: /* ARM_CKCTL */
  1411. diff = s->clkm.arm_ckctl ^ value;
  1412. s->clkm.arm_ckctl = value & 0x7fff;
  1413. omap_clkm_ckctl_update(s, diff, value);
  1414. return;
  1415. case 0x04: /* ARM_IDLECT1 */
  1416. diff = s->clkm.arm_idlect1 ^ value;
  1417. s->clkm.arm_idlect1 = value & 0x0fff;
  1418. omap_clkm_idlect1_update(s, diff, value);
  1419. return;
  1420. case 0x08: /* ARM_IDLECT2 */
  1421. diff = s->clkm.arm_idlect2 ^ value;
  1422. s->clkm.arm_idlect2 = value & 0x07ff;
  1423. omap_clkm_idlect2_update(s, diff, value);
  1424. return;
  1425. case 0x0c: /* ARM_EWUPCT */
  1426. s->clkm.arm_ewupct = value & 0x003f;
  1427. return;
  1428. case 0x10: /* ARM_RSTCT1 */
  1429. diff = s->clkm.arm_rstct1 ^ value;
  1430. s->clkm.arm_rstct1 = value & 0x0007;
  1431. if (value & 9) {
  1432. qemu_system_reset_request();
  1433. s->clkm.cold_start = 0xa;
  1434. }
  1435. if (diff & ~value & 4) { /* DSP_RST */
  1436. omap_mpui_reset(s);
  1437. omap_tipb_bridge_reset(s->private_tipb);
  1438. omap_tipb_bridge_reset(s->public_tipb);
  1439. }
  1440. if (diff & 2) { /* DSP_EN */
  1441. clk = omap_findclk(s, "dsp_ck");
  1442. omap_clk_canidle(clk, (~value >> 1) & 1);
  1443. }
  1444. return;
  1445. case 0x14: /* ARM_RSTCT2 */
  1446. s->clkm.arm_rstct2 = value & 0x0001;
  1447. return;
  1448. case 0x18: /* ARM_SYSST */
  1449. if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
  1450. s->clkm.clocking_scheme = (value >> 11) & 7;
  1451. printf("%s: clocking scheme set to %s\n", __FUNCTION__,
  1452. clkschemename[s->clkm.clocking_scheme]);
  1453. }
  1454. s->clkm.cold_start &= value & 0x3f;
  1455. return;
  1456. case 0x1c: /* ARM_CKOUT1 */
  1457. diff = s->clkm.arm_ckout1 ^ value;
  1458. s->clkm.arm_ckout1 = value & 0x003f;
  1459. omap_clkm_ckout1_update(s, diff, value);
  1460. return;
  1461. case 0x20: /* ARM_CKOUT2 */
  1462. default:
  1463. OMAP_BAD_REG(addr);
  1464. }
  1465. }
  1466. static const MemoryRegionOps omap_clkm_ops = {
  1467. .read = omap_clkm_read,
  1468. .write = omap_clkm_write,
  1469. .endianness = DEVICE_NATIVE_ENDIAN,
  1470. };
  1471. static uint64_t omap_clkdsp_read(void *opaque, target_phys_addr_t addr,
  1472. unsigned size)
  1473. {
  1474. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  1475. if (size != 2) {
  1476. return omap_badwidth_read16(opaque, addr);
  1477. }
  1478. switch (addr) {
  1479. case 0x04: /* DSP_IDLECT1 */
  1480. return s->clkm.dsp_idlect1;
  1481. case 0x08: /* DSP_IDLECT2 */
  1482. return s->clkm.dsp_idlect2;
  1483. case 0x14: /* DSP_RSTCT2 */
  1484. return s->clkm.dsp_rstct2;
  1485. case 0x18: /* DSP_SYSST */
  1486. return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
  1487. (s->cpu->env.halted << 6); /* Quite useless... */
  1488. }
  1489. OMAP_BAD_REG(addr);
  1490. return 0;
  1491. }
  1492. static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
  1493. uint16_t diff, uint16_t value)
  1494. {
  1495. omap_clk clk;
  1496. SET_CANIDLE("dspxor_ck", 1); /* IDLXORP_DSP */
  1497. }
  1498. static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
  1499. uint16_t diff, uint16_t value)
  1500. {
  1501. omap_clk clk;
  1502. SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */
  1503. }
  1504. static void omap_clkdsp_write(void *opaque, target_phys_addr_t addr,
  1505. uint64_t value, unsigned size)
  1506. {
  1507. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  1508. uint16_t diff;
  1509. if (size != 2) {
  1510. return omap_badwidth_write16(opaque, addr, value);
  1511. }
  1512. switch (addr) {
  1513. case 0x04: /* DSP_IDLECT1 */
  1514. diff = s->clkm.dsp_idlect1 ^ value;
  1515. s->clkm.dsp_idlect1 = value & 0x01f7;
  1516. omap_clkdsp_idlect1_update(s, diff, value);
  1517. break;
  1518. case 0x08: /* DSP_IDLECT2 */
  1519. s->clkm.dsp_idlect2 = value & 0x0037;
  1520. diff = s->clkm.dsp_idlect1 ^ value;
  1521. omap_clkdsp_idlect2_update(s, diff, value);
  1522. break;
  1523. case 0x14: /* DSP_RSTCT2 */
  1524. s->clkm.dsp_rstct2 = value & 0x0001;
  1525. break;
  1526. case 0x18: /* DSP_SYSST */
  1527. s->clkm.cold_start &= value & 0x3f;
  1528. break;
  1529. default:
  1530. OMAP_BAD_REG(addr);
  1531. }
  1532. }
  1533. static const MemoryRegionOps omap_clkdsp_ops = {
  1534. .read = omap_clkdsp_read,
  1535. .write = omap_clkdsp_write,
  1536. .endianness = DEVICE_NATIVE_ENDIAN,
  1537. };
  1538. static void omap_clkm_reset(struct omap_mpu_state_s *s)
  1539. {
  1540. if (s->wdt && s->wdt->reset)
  1541. s->clkm.cold_start = 0x6;
  1542. s->clkm.clocking_scheme = 0;
  1543. omap_clkm_ckctl_update(s, ~0, 0x3000);
  1544. s->clkm.arm_ckctl = 0x3000;
  1545. omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
  1546. s->clkm.arm_idlect1 = 0x0400;
  1547. omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
  1548. s->clkm.arm_idlect2 = 0x0100;
  1549. s->clkm.arm_ewupct = 0x003f;
  1550. s->clkm.arm_rstct1 = 0x0000;
  1551. s->clkm.arm_rstct2 = 0x0000;
  1552. s->clkm.arm_ckout1 = 0x0015;
  1553. s->clkm.dpll1_mode = 0x2002;
  1554. omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
  1555. s->clkm.dsp_idlect1 = 0x0040;
  1556. omap_clkdsp_idlect2_update(s, ~0, 0x0000);
  1557. s->clkm.dsp_idlect2 = 0x0000;
  1558. s->clkm.dsp_rstct2 = 0x0000;
  1559. }
  1560. static void omap_clkm_init(MemoryRegion *memory, target_phys_addr_t mpu_base,
  1561. target_phys_addr_t dsp_base, struct omap_mpu_state_s *s)
  1562. {
  1563. memory_region_init_io(&s->clkm_iomem, &omap_clkm_ops, s,
  1564. "omap-clkm", 0x100);
  1565. memory_region_init_io(&s->clkdsp_iomem, &omap_clkdsp_ops, s,
  1566. "omap-clkdsp", 0x1000);
  1567. s->clkm.arm_idlect1 = 0x03ff;
  1568. s->clkm.arm_idlect2 = 0x0100;
  1569. s->clkm.dsp_idlect1 = 0x0002;
  1570. omap_clkm_reset(s);
  1571. s->clkm.cold_start = 0x3a;
  1572. memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
  1573. memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
  1574. }
  1575. /* MPU I/O */
  1576. struct omap_mpuio_s {
  1577. qemu_irq irq;
  1578. qemu_irq kbd_irq;
  1579. qemu_irq *in;
  1580. qemu_irq handler[16];
  1581. qemu_irq wakeup;
  1582. MemoryRegion iomem;
  1583. uint16_t inputs;
  1584. uint16_t outputs;
  1585. uint16_t dir;
  1586. uint16_t edge;
  1587. uint16_t mask;
  1588. uint16_t ints;
  1589. uint16_t debounce;
  1590. uint16_t latch;
  1591. uint8_t event;
  1592. uint8_t buttons[5];
  1593. uint8_t row_latch;
  1594. uint8_t cols;
  1595. int kbd_mask;
  1596. int clk;
  1597. };
  1598. static void omap_mpuio_set(void *opaque, int line, int level)
  1599. {
  1600. struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
  1601. uint16_t prev = s->inputs;
  1602. if (level)
  1603. s->inputs |= 1 << line;
  1604. else
  1605. s->inputs &= ~(1 << line);
  1606. if (((1 << line) & s->dir & ~s->mask) && s->clk) {
  1607. if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
  1608. s->ints |= 1 << line;
  1609. qemu_irq_raise(s->irq);
  1610. /* TODO: wakeup */
  1611. }
  1612. if ((s->event & (1 << 0)) && /* SET_GPIO_EVENT_MODE */
  1613. (s->event >> 1) == line) /* PIN_SELECT */
  1614. s->latch = s->inputs;
  1615. }
  1616. }
  1617. static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
  1618. {
  1619. int i;
  1620. uint8_t *row, rows = 0, cols = ~s->cols;
  1621. for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
  1622. if (*row & cols)
  1623. rows |= i;
  1624. qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
  1625. s->row_latch = ~rows;
  1626. }
  1627. static uint64_t omap_mpuio_read(void *opaque, target_phys_addr_t addr,
  1628. unsigned size)
  1629. {
  1630. struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
  1631. int offset = addr & OMAP_MPUI_REG_MASK;
  1632. uint16_t ret;
  1633. if (size != 2) {
  1634. return omap_badwidth_read16(opaque, addr);
  1635. }
  1636. switch (offset) {
  1637. case 0x00: /* INPUT_LATCH */
  1638. return s->inputs;
  1639. case 0x04: /* OUTPUT_REG */
  1640. return s->outputs;
  1641. case 0x08: /* IO_CNTL */
  1642. return s->dir;
  1643. case 0x10: /* KBR_LATCH */
  1644. return s->row_latch;
  1645. case 0x14: /* KBC_REG */
  1646. return s->cols;
  1647. case 0x18: /* GPIO_EVENT_MODE_REG */
  1648. return s->event;
  1649. case 0x1c: /* GPIO_INT_EDGE_REG */
  1650. return s->edge;
  1651. case 0x20: /* KBD_INT */
  1652. return (~s->row_latch & 0x1f) && !s->kbd_mask;
  1653. case 0x24: /* GPIO_INT */
  1654. ret = s->ints;
  1655. s->ints &= s->mask;
  1656. if (ret)
  1657. qemu_irq_lower(s->irq);
  1658. return ret;
  1659. case 0x28: /* KBD_MASKIT */
  1660. return s->kbd_mask;
  1661. case 0x2c: /* GPIO_MASKIT */
  1662. return s->mask;
  1663. case 0x30: /* GPIO_DEBOUNCING_REG */
  1664. return s->debounce;
  1665. case 0x34: /* GPIO_LATCH_REG */
  1666. return s->latch;
  1667. }
  1668. OMAP_BAD_REG(addr);
  1669. return 0;
  1670. }
  1671. static void omap_mpuio_write(void *opaque, target_phys_addr_t addr,
  1672. uint64_t value, unsigned size)
  1673. {
  1674. struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
  1675. int offset = addr & OMAP_MPUI_REG_MASK;
  1676. uint16_t diff;
  1677. int ln;
  1678. if (size != 2) {
  1679. return omap_badwidth_write16(opaque, addr, value);
  1680. }
  1681. switch (offset) {
  1682. case 0x04: /* OUTPUT_REG */
  1683. diff = (s->outputs ^ value) & ~s->dir;
  1684. s->outputs = value;
  1685. while ((ln = ffs(diff))) {
  1686. ln --;
  1687. if (s->handler[ln])
  1688. qemu_set_irq(s->handler[ln], (value >> ln) & 1);
  1689. diff &= ~(1 << ln);
  1690. }
  1691. break;
  1692. case 0x08: /* IO_CNTL */
  1693. diff = s->outputs & (s->dir ^ value);
  1694. s->dir = value;
  1695. value = s->outputs & ~s->dir;
  1696. while ((ln = ffs(diff))) {
  1697. ln --;
  1698. if (s->handler[ln])
  1699. qemu_set_irq(s->handler[ln], (value >> ln) & 1);
  1700. diff &= ~(1 << ln);
  1701. }
  1702. break;
  1703. case 0x14: /* KBC_REG */
  1704. s->cols = value;
  1705. omap_mpuio_kbd_update(s);
  1706. break;
  1707. case 0x18: /* GPIO_EVENT_MODE_REG */
  1708. s->event = value & 0x1f;
  1709. break;
  1710. case 0x1c: /* GPIO_INT_EDGE_REG */
  1711. s->edge = value;
  1712. break;
  1713. case 0x28: /* KBD_MASKIT */
  1714. s->kbd_mask = value & 1;
  1715. omap_mpuio_kbd_update(s);
  1716. break;
  1717. case 0x2c: /* GPIO_MASKIT */
  1718. s->mask = value;
  1719. break;
  1720. case 0x30: /* GPIO_DEBOUNCING_REG */
  1721. s->debounce = value & 0x1ff;
  1722. break;
  1723. case 0x00: /* INPUT_LATCH */
  1724. case 0x10: /* KBR_LATCH */
  1725. case 0x20: /* KBD_INT */
  1726. case 0x24: /* GPIO_INT */
  1727. case 0x34: /* GPIO_LATCH_REG */
  1728. OMAP_RO_REG(addr);
  1729. return;
  1730. default:
  1731. OMAP_BAD_REG(addr);
  1732. return;
  1733. }
  1734. }
  1735. static const MemoryRegionOps omap_mpuio_ops = {
  1736. .read = omap_mpuio_read,
  1737. .write = omap_mpuio_write,
  1738. .endianness = DEVICE_NATIVE_ENDIAN,
  1739. };
  1740. static void omap_mpuio_reset(struct omap_mpuio_s *s)
  1741. {
  1742. s->inputs = 0;
  1743. s->outputs = 0;
  1744. s->dir = ~0;
  1745. s->event = 0;
  1746. s->edge = 0;
  1747. s->kbd_mask = 0;
  1748. s->mask = 0;
  1749. s->debounce = 0;
  1750. s->latch = 0;
  1751. s->ints = 0;
  1752. s->row_latch = 0x1f;
  1753. s->clk = 1;
  1754. }
  1755. static void omap_mpuio_onoff(void *opaque, int line, int on)
  1756. {
  1757. struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
  1758. s->clk = on;
  1759. if (on)
  1760. omap_mpuio_kbd_update(s);
  1761. }
  1762. static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
  1763. target_phys_addr_t base,
  1764. qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
  1765. omap_clk clk)
  1766. {
  1767. struct omap_mpuio_s *s = (struct omap_mpuio_s *)
  1768. g_malloc0(sizeof(struct omap_mpuio_s));
  1769. s->irq = gpio_int;
  1770. s->kbd_irq = kbd_int;
  1771. s->wakeup = wakeup;
  1772. s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
  1773. omap_mpuio_reset(s);
  1774. memory_region_init_io(&s->iomem, &omap_mpuio_ops, s,
  1775. "omap-mpuio", 0x800);
  1776. memory_region_add_subregion(memory, base, &s->iomem);
  1777. omap_clk_adduser(clk, qemu_allocate_irqs(omap_mpuio_onoff, s, 1)[0]);
  1778. return s;
  1779. }
  1780. qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
  1781. {
  1782. return s->in;
  1783. }
  1784. void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
  1785. {
  1786. if (line >= 16 || line < 0)
  1787. hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
  1788. s->handler[line] = handler;
  1789. }
  1790. void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
  1791. {
  1792. if (row >= 5 || row < 0)
  1793. hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
  1794. if (down)
  1795. s->buttons[row] |= 1 << col;
  1796. else
  1797. s->buttons[row] &= ~(1 << col);
  1798. omap_mpuio_kbd_update(s);
  1799. }
  1800. /* MicroWire Interface */
  1801. struct omap_uwire_s {
  1802. MemoryRegion iomem;
  1803. qemu_irq txirq;
  1804. qemu_irq rxirq;
  1805. qemu_irq txdrq;
  1806. uint16_t txbuf;
  1807. uint16_t rxbuf;
  1808. uint16_t control;
  1809. uint16_t setup[5];
  1810. uWireSlave *chip[4];
  1811. };
  1812. static void omap_uwire_transfer_start(struct omap_uwire_s *s)
  1813. {
  1814. int chipselect = (s->control >> 10) & 3; /* INDEX */
  1815. uWireSlave *slave = s->chip[chipselect];
  1816. if ((s->control >> 5) & 0x1f) { /* NB_BITS_WR */
  1817. if (s->control & (1 << 12)) /* CS_CMD */
  1818. if (slave && slave->send)
  1819. slave->send(slave->opaque,
  1820. s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
  1821. s->control &= ~(1 << 14); /* CSRB */
  1822. /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
  1823. * a DRQ. When is the level IRQ supposed to be reset? */
  1824. }
  1825. if ((s->control >> 0) & 0x1f) { /* NB_BITS_RD */
  1826. if (s->control & (1 << 12)) /* CS_CMD */
  1827. if (slave && slave->receive)
  1828. s->rxbuf = slave->receive(slave->opaque);
  1829. s->control |= 1 << 15; /* RDRB */
  1830. /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
  1831. * a DRQ. When is the level IRQ supposed to be reset? */
  1832. }
  1833. }
  1834. static uint64_t omap_uwire_read(void *opaque, target_phys_addr_t addr,
  1835. unsigned size)
  1836. {
  1837. struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
  1838. int offset = addr & OMAP_MPUI_REG_MASK;
  1839. if (size != 2) {
  1840. return omap_badwidth_read16(opaque, addr);
  1841. }
  1842. switch (offset) {
  1843. case 0x00: /* RDR */
  1844. s->control &= ~(1 << 15); /* RDRB */
  1845. return s->rxbuf;
  1846. case 0x04: /* CSR */
  1847. return s->control;
  1848. case 0x08: /* SR1 */
  1849. return s->setup[0];
  1850. case 0x0c: /* SR2 */
  1851. return s->setup[1];
  1852. case 0x10: /* SR3 */
  1853. return s->setup[2];
  1854. case 0x14: /* SR4 */
  1855. return s->setup[3];
  1856. case 0x18: /* SR5 */
  1857. return s->setup[4];
  1858. }
  1859. OMAP_BAD_REG(addr);
  1860. return 0;
  1861. }
  1862. static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
  1863. uint64_t value, unsigned size)
  1864. {
  1865. struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
  1866. int offset = addr & OMAP_MPUI_REG_MASK;
  1867. if (size != 2) {
  1868. return omap_badwidth_write16(opaque, addr, value);
  1869. }
  1870. switch (offset) {
  1871. case 0x00: /* TDR */
  1872. s->txbuf = value; /* TD */
  1873. if ((s->setup[4] & (1 << 2)) && /* AUTO_TX_EN */
  1874. ((s->setup[4] & (1 << 3)) || /* CS_TOGGLE_TX_EN */
  1875. (s->control & (1 << 12)))) { /* CS_CMD */
  1876. s->control |= 1 << 14; /* CSRB */
  1877. omap_uwire_transfer_start(s);
  1878. }
  1879. break;
  1880. case 0x04: /* CSR */
  1881. s->control = value & 0x1fff;
  1882. if (value & (1 << 13)) /* START */
  1883. omap_uwire_transfer_start(s);
  1884. break;
  1885. case 0x08: /* SR1 */
  1886. s->setup[0] = value & 0x003f;
  1887. break;
  1888. case 0x0c: /* SR2 */
  1889. s->setup[1] = value & 0x0fc0;
  1890. break;
  1891. case 0x10: /* SR3 */
  1892. s->setup[2] = value & 0x0003;
  1893. break;
  1894. case 0x14: /* SR4 */
  1895. s->setup[3] = value & 0x0001;
  1896. break;
  1897. case 0x18: /* SR5 */
  1898. s->setup[4] = value & 0x000f;
  1899. break;
  1900. default:
  1901. OMAP_BAD_REG(addr);
  1902. return;
  1903. }
  1904. }
  1905. static const MemoryRegionOps omap_uwire_ops = {
  1906. .read = omap_uwire_read,
  1907. .write = omap_uwire_write,
  1908. .endianness = DEVICE_NATIVE_ENDIAN,
  1909. };
  1910. static void omap_uwire_reset(struct omap_uwire_s *s)
  1911. {
  1912. s->control = 0;
  1913. s->setup[0] = 0;
  1914. s->setup[1] = 0;
  1915. s->setup[2] = 0;
  1916. s->setup[3] = 0;
  1917. s->setup[4] = 0;
  1918. }
  1919. static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
  1920. target_phys_addr_t base,
  1921. qemu_irq txirq, qemu_irq rxirq,
  1922. qemu_irq dma,
  1923. omap_clk clk)
  1924. {
  1925. struct omap_uwire_s *s = (struct omap_uwire_s *)
  1926. g_malloc0(sizeof(struct omap_uwire_s));
  1927. s->txirq = txirq;
  1928. s->rxirq = rxirq;
  1929. s->txdrq = dma;
  1930. omap_uwire_reset(s);
  1931. memory_region_init_io(&s->iomem, &omap_uwire_ops, s, "omap-uwire", 0x800);
  1932. memory_region_add_subregion(system_memory, base, &s->iomem);
  1933. return s;
  1934. }
  1935. void omap_uwire_attach(struct omap_uwire_s *s,
  1936. uWireSlave *slave, int chipselect)
  1937. {
  1938. if (chipselect < 0 || chipselect > 3) {
  1939. fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
  1940. exit(-1);
  1941. }
  1942. s->chip[chipselect] = slave;
  1943. }
  1944. /* Pseudonoise Pulse-Width Light Modulator */
  1945. struct omap_pwl_s {
  1946. MemoryRegion iomem;
  1947. uint8_t output;
  1948. uint8_t level;
  1949. uint8_t enable;
  1950. int clk;
  1951. };
  1952. static void omap_pwl_update(struct omap_pwl_s *s)
  1953. {
  1954. int output = (s->clk && s->enable) ? s->level : 0;
  1955. if (output != s->output) {
  1956. s->output = output;
  1957. printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
  1958. }
  1959. }
  1960. static uint64_t omap_pwl_read(void *opaque, target_phys_addr_t addr,
  1961. unsigned size)
  1962. {
  1963. struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
  1964. int offset = addr & OMAP_MPUI_REG_MASK;
  1965. if (size != 1) {
  1966. return omap_badwidth_read8(opaque, addr);
  1967. }
  1968. switch (offset) {
  1969. case 0x00: /* PWL_LEVEL */
  1970. return s->level;
  1971. case 0x04: /* PWL_CTRL */
  1972. return s->enable;
  1973. }
  1974. OMAP_BAD_REG(addr);
  1975. return 0;
  1976. }
  1977. static void omap_pwl_write(void *opaque, target_phys_addr_t addr,
  1978. uint64_t value, unsigned size)
  1979. {
  1980. struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
  1981. int offset = addr & OMAP_MPUI_REG_MASK;
  1982. if (size != 1) {
  1983. return omap_badwidth_write8(opaque, addr, value);
  1984. }
  1985. switch (offset) {
  1986. case 0x00: /* PWL_LEVEL */
  1987. s->level = value;
  1988. omap_pwl_update(s);
  1989. break;
  1990. case 0x04: /* PWL_CTRL */
  1991. s->enable = value & 1;
  1992. omap_pwl_update(s);
  1993. break;
  1994. default:
  1995. OMAP_BAD_REG(addr);
  1996. return;
  1997. }
  1998. }
  1999. static const MemoryRegionOps omap_pwl_ops = {
  2000. .read = omap_pwl_read,
  2001. .write = omap_pwl_write,
  2002. .endianness = DEVICE_NATIVE_ENDIAN,
  2003. };
  2004. static void omap_pwl_reset(struct omap_pwl_s *s)
  2005. {
  2006. s->output = 0;
  2007. s->level = 0;
  2008. s->enable = 0;
  2009. s->clk = 1;
  2010. omap_pwl_update(s);
  2011. }
  2012. static void omap_pwl_clk_update(void *opaque, int line, int on)
  2013. {
  2014. struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
  2015. s->clk = on;
  2016. omap_pwl_update(s);
  2017. }
  2018. static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
  2019. target_phys_addr_t base,
  2020. omap_clk clk)
  2021. {
  2022. struct omap_pwl_s *s = g_malloc0(sizeof(*s));
  2023. omap_pwl_reset(s);
  2024. memory_region_init_io(&s->iomem, &omap_pwl_ops, s,
  2025. "omap-pwl", 0x800);
  2026. memory_region_add_subregion(system_memory, base, &s->iomem);
  2027. omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
  2028. return s;
  2029. }
  2030. /* Pulse-Width Tone module */
  2031. struct omap_pwt_s {
  2032. MemoryRegion iomem;
  2033. uint8_t frc;
  2034. uint8_t vrc;
  2035. uint8_t gcr;
  2036. omap_clk clk;
  2037. };
  2038. static uint64_t omap_pwt_read(void *opaque, target_phys_addr_t addr,
  2039. unsigned size)
  2040. {
  2041. struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
  2042. int offset = addr & OMAP_MPUI_REG_MASK;
  2043. if (size != 1) {
  2044. return omap_badwidth_read8(opaque, addr);
  2045. }
  2046. switch (offset) {
  2047. case 0x00: /* FRC */
  2048. return s->frc;
  2049. case 0x04: /* VCR */
  2050. return s->vrc;
  2051. case 0x08: /* GCR */
  2052. return s->gcr;
  2053. }
  2054. OMAP_BAD_REG(addr);
  2055. return 0;
  2056. }
  2057. static void omap_pwt_write(void *opaque, target_phys_addr_t addr,
  2058. uint64_t value, unsigned size)
  2059. {
  2060. struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
  2061. int offset = addr & OMAP_MPUI_REG_MASK;
  2062. if (size != 1) {
  2063. return omap_badwidth_write8(opaque, addr, value);
  2064. }
  2065. switch (offset) {
  2066. case 0x00: /* FRC */
  2067. s->frc = value & 0x3f;
  2068. break;
  2069. case 0x04: /* VRC */
  2070. if ((value ^ s->vrc) & 1) {
  2071. if (value & 1)
  2072. printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
  2073. /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
  2074. ((omap_clk_getrate(s->clk) >> 3) /
  2075. /* Pre-multiplexer divider */
  2076. ((s->gcr & 2) ? 1 : 154) /
  2077. /* Octave multiplexer */
  2078. (2 << (value & 3)) *
  2079. /* 101/107 divider */
  2080. ((value & (1 << 2)) ? 101 : 107) *
  2081. /* 49/55 divider */
  2082. ((value & (1 << 3)) ? 49 : 55) *
  2083. /* 50/63 divider */
  2084. ((value & (1 << 4)) ? 50 : 63) *
  2085. /* 80/127 divider */
  2086. ((value & (1 << 5)) ? 80 : 127) /
  2087. (107 * 55 * 63 * 127)));
  2088. else
  2089. printf("%s: silence!\n", __FUNCTION__);
  2090. }
  2091. s->vrc = value & 0x7f;
  2092. break;
  2093. case 0x08: /* GCR */
  2094. s->gcr = value & 3;
  2095. break;
  2096. default:
  2097. OMAP_BAD_REG(addr);
  2098. return;
  2099. }
  2100. }
  2101. static const MemoryRegionOps omap_pwt_ops = {
  2102. .read =omap_pwt_read,
  2103. .write = omap_pwt_write,
  2104. .endianness = DEVICE_NATIVE_ENDIAN,
  2105. };
  2106. static void omap_pwt_reset(struct omap_pwt_s *s)
  2107. {
  2108. s->frc = 0;
  2109. s->vrc = 0;
  2110. s->gcr = 0;
  2111. }
  2112. static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
  2113. target_phys_addr_t base,
  2114. omap_clk clk)
  2115. {
  2116. struct omap_pwt_s *s = g_malloc0(sizeof(*s));
  2117. s->clk = clk;
  2118. omap_pwt_reset(s);
  2119. memory_region_init_io(&s->iomem, &omap_pwt_ops, s,
  2120. "omap-pwt", 0x800);
  2121. memory_region_add_subregion(system_memory, base, &s->iomem);
  2122. return s;
  2123. }
  2124. /* Real-time Clock module */
  2125. struct omap_rtc_s {
  2126. MemoryRegion iomem;
  2127. qemu_irq irq;
  2128. qemu_irq alarm;
  2129. QEMUTimer *clk;
  2130. uint8_t interrupts;
  2131. uint8_t status;
  2132. int16_t comp_reg;
  2133. int running;
  2134. int pm_am;
  2135. int auto_comp;
  2136. int round;
  2137. struct tm alarm_tm;
  2138. time_t alarm_ti;
  2139. struct tm current_tm;
  2140. time_t ti;
  2141. uint64_t tick;
  2142. };
  2143. static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
  2144. {
  2145. /* s->alarm is level-triggered */
  2146. qemu_set_irq(s->alarm, (s->status >> 6) & 1);
  2147. }
  2148. static void omap_rtc_alarm_update(struct omap_rtc_s *s)
  2149. {
  2150. s->alarm_ti = mktimegm(&s->alarm_tm);
  2151. if (s->alarm_ti == -1)
  2152. printf("%s: conversion failed\n", __FUNCTION__);
  2153. }
  2154. static uint64_t omap_rtc_read(void *opaque, target_phys_addr_t addr,
  2155. unsigned size)
  2156. {
  2157. struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
  2158. int offset = addr & OMAP_MPUI_REG_MASK;
  2159. uint8_t i;
  2160. if (size != 1) {
  2161. return omap_badwidth_read8(opaque, addr);
  2162. }
  2163. switch (offset) {
  2164. case 0x00: /* SECONDS_REG */
  2165. return to_bcd(s->current_tm.tm_sec);
  2166. case 0x04: /* MINUTES_REG */
  2167. return to_bcd(s->current_tm.tm_min);
  2168. case 0x08: /* HOURS_REG */
  2169. if (s->pm_am)
  2170. return ((s->current_tm.tm_hour > 11) << 7) |
  2171. to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
  2172. else
  2173. return to_bcd(s->current_tm.tm_hour);
  2174. case 0x0c: /* DAYS_REG */
  2175. return to_bcd(s->current_tm.tm_mday);
  2176. case 0x10: /* MONTHS_REG */
  2177. return to_bcd(s->current_tm.tm_mon + 1);
  2178. case 0x14: /* YEARS_REG */
  2179. return to_bcd(s->current_tm.tm_year % 100);
  2180. case 0x18: /* WEEK_REG */
  2181. return s->current_tm.tm_wday;
  2182. case 0x20: /* ALARM_SECONDS_REG */
  2183. return to_bcd(s->alarm_tm.tm_sec);
  2184. case 0x24: /* ALARM_MINUTES_REG */
  2185. return to_bcd(s->alarm_tm.tm_min);
  2186. case 0x28: /* ALARM_HOURS_REG */
  2187. if (s->pm_am)
  2188. return ((s->alarm_tm.tm_hour > 11) << 7) |
  2189. to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
  2190. else
  2191. return to_bcd(s->alarm_tm.tm_hour);
  2192. case 0x2c: /* ALARM_DAYS_REG */
  2193. return to_bcd(s->alarm_tm.tm_mday);
  2194. case 0x30: /* ALARM_MONTHS_REG */
  2195. return to_bcd(s->alarm_tm.tm_mon + 1);
  2196. case 0x34: /* ALARM_YEARS_REG */
  2197. return to_bcd(s->alarm_tm.tm_year % 100);
  2198. case 0x40: /* RTC_CTRL_REG */
  2199. return (s->pm_am << 3) | (s->auto_comp << 2) |
  2200. (s->round << 1) | s->running;
  2201. case 0x44: /* RTC_STATUS_REG */
  2202. i = s->status;
  2203. s->status &= ~0x3d;
  2204. return i;
  2205. case 0x48: /* RTC_INTERRUPTS_REG */
  2206. return s->interrupts;
  2207. case 0x4c: /* RTC_COMP_LSB_REG */
  2208. return ((uint16_t) s->comp_reg) & 0xff;
  2209. case 0x50: /* RTC_COMP_MSB_REG */
  2210. return ((uint16_t) s->comp_reg) >> 8;
  2211. }
  2212. OMAP_BAD_REG(addr);
  2213. return 0;
  2214. }
  2215. static void omap_rtc_write(void *opaque, target_phys_addr_t addr,
  2216. uint64_t value, unsigned size)
  2217. {
  2218. struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
  2219. int offset = addr & OMAP_MPUI_REG_MASK;
  2220. struct tm new_tm;
  2221. time_t ti[2];
  2222. if (size != 1) {
  2223. return omap_badwidth_write8(opaque, addr, value);
  2224. }
  2225. switch (offset) {
  2226. case 0x00: /* SECONDS_REG */
  2227. #ifdef ALMDEBUG
  2228. printf("RTC SEC_REG <-- %02x\n", value);
  2229. #endif
  2230. s->ti -= s->current_tm.tm_sec;
  2231. s->ti += from_bcd(value);
  2232. return;
  2233. case 0x04: /* MINUTES_REG */
  2234. #ifdef ALMDEBUG
  2235. printf("RTC MIN_REG <-- %02x\n", value);
  2236. #endif
  2237. s->ti -= s->current_tm.tm_min * 60;
  2238. s->ti += from_bcd(value) * 60;
  2239. return;
  2240. case 0x08: /* HOURS_REG */
  2241. #ifdef ALMDEBUG
  2242. printf("RTC HRS_REG <-- %02x\n", value);
  2243. #endif
  2244. s->ti -= s->current_tm.tm_hour * 3600;
  2245. if (s->pm_am) {
  2246. s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
  2247. s->ti += ((value >> 7) & 1) * 43200;
  2248. } else
  2249. s->ti += from_bcd(value & 0x3f) * 3600;
  2250. return;
  2251. case 0x0c: /* DAYS_REG */
  2252. #ifdef ALMDEBUG
  2253. printf("RTC DAY_REG <-- %02x\n", value);
  2254. #endif
  2255. s->ti -= s->current_tm.tm_mday * 86400;
  2256. s->ti += from_bcd(value) * 86400;
  2257. return;
  2258. case 0x10: /* MONTHS_REG */
  2259. #ifdef ALMDEBUG
  2260. printf("RTC MTH_REG <-- %02x\n", value);
  2261. #endif
  2262. memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
  2263. new_tm.tm_mon = from_bcd(value);
  2264. ti[0] = mktimegm(&s->current_tm);
  2265. ti[1] = mktimegm(&new_tm);
  2266. if (ti[0] != -1 && ti[1] != -1) {
  2267. s->ti -= ti[0];
  2268. s->ti += ti[1];
  2269. } else {
  2270. /* A less accurate version */
  2271. s->ti -= s->current_tm.tm_mon * 2592000;
  2272. s->ti += from_bcd(value) * 2592000;
  2273. }
  2274. return;
  2275. case 0x14: /* YEARS_REG */
  2276. #ifdef ALMDEBUG
  2277. printf("RTC YRS_REG <-- %02x\n", value);
  2278. #endif
  2279. memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
  2280. new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
  2281. ti[0] = mktimegm(&s->current_tm);
  2282. ti[1] = mktimegm(&new_tm);
  2283. if (ti[0] != -1 && ti[1] != -1) {
  2284. s->ti -= ti[0];
  2285. s->ti += ti[1];
  2286. } else {
  2287. /* A less accurate version */
  2288. s->ti -= (s->current_tm.tm_year % 100) * 31536000;
  2289. s->ti += from_bcd(value) * 31536000;
  2290. }
  2291. return;
  2292. case 0x18: /* WEEK_REG */
  2293. return; /* Ignored */
  2294. case 0x20: /* ALARM_SECONDS_REG */
  2295. #ifdef ALMDEBUG
  2296. printf("ALM SEC_REG <-- %02x\n", value);
  2297. #endif
  2298. s->alarm_tm.tm_sec = from_bcd(value);
  2299. omap_rtc_alarm_update(s);
  2300. return;
  2301. case 0x24: /* ALARM_MINUTES_REG */
  2302. #ifdef ALMDEBUG
  2303. printf("ALM MIN_REG <-- %02x\n", value);
  2304. #endif
  2305. s->alarm_tm.tm_min = from_bcd(value);
  2306. omap_rtc_alarm_update(s);
  2307. return;
  2308. case 0x28: /* ALARM_HOURS_REG */
  2309. #ifdef ALMDEBUG
  2310. printf("ALM HRS_REG <-- %02x\n", value);
  2311. #endif
  2312. if (s->pm_am)
  2313. s->alarm_tm.tm_hour =
  2314. ((from_bcd(value & 0x3f)) % 12) +
  2315. ((value >> 7) & 1) * 12;
  2316. else
  2317. s->alarm_tm.tm_hour = from_bcd(value);
  2318. omap_rtc_alarm_update(s);
  2319. return;
  2320. case 0x2c: /* ALARM_DAYS_REG */
  2321. #ifdef ALMDEBUG
  2322. printf("ALM DAY_REG <-- %02x\n", value);
  2323. #endif
  2324. s->alarm_tm.tm_mday = from_bcd(value);
  2325. omap_rtc_alarm_update(s);
  2326. return;
  2327. case 0x30: /* ALARM_MONTHS_REG */
  2328. #ifdef ALMDEBUG
  2329. printf("ALM MON_REG <-- %02x\n", value);
  2330. #endif
  2331. s->alarm_tm.tm_mon = from_bcd(value);
  2332. omap_rtc_alarm_update(s);
  2333. return;
  2334. case 0x34: /* ALARM_YEARS_REG */
  2335. #ifdef ALMDEBUG
  2336. printf("ALM YRS_REG <-- %02x\n", value);
  2337. #endif
  2338. s->alarm_tm.tm_year = from_bcd(value);
  2339. omap_rtc_alarm_update(s);
  2340. return;
  2341. case 0x40: /* RTC_CTRL_REG */
  2342. #ifdef ALMDEBUG
  2343. printf("RTC CONTROL <-- %02x\n", value);
  2344. #endif
  2345. s->pm_am = (value >> 3) & 1;
  2346. s->auto_comp = (value >> 2) & 1;
  2347. s->round = (value >> 1) & 1;
  2348. s->running = value & 1;
  2349. s->status &= 0xfd;
  2350. s->status |= s->running << 1;
  2351. return;
  2352. case 0x44: /* RTC_STATUS_REG */
  2353. #ifdef ALMDEBUG
  2354. printf("RTC STATUSL <-- %02x\n", value);
  2355. #endif
  2356. s->status &= ~((value & 0xc0) ^ 0x80);
  2357. omap_rtc_interrupts_update(s);
  2358. return;
  2359. case 0x48: /* RTC_INTERRUPTS_REG */
  2360. #ifdef ALMDEBUG
  2361. printf("RTC INTRS <-- %02x\n", value);
  2362. #endif
  2363. s->interrupts = value;
  2364. return;
  2365. case 0x4c: /* RTC_COMP_LSB_REG */
  2366. #ifdef ALMDEBUG
  2367. printf("RTC COMPLSB <-- %02x\n", value);
  2368. #endif
  2369. s->comp_reg &= 0xff00;
  2370. s->comp_reg |= 0x00ff & value;
  2371. return;
  2372. case 0x50: /* RTC_COMP_MSB_REG */
  2373. #ifdef ALMDEBUG
  2374. printf("RTC COMPMSB <-- %02x\n", value);
  2375. #endif
  2376. s->comp_reg &= 0x00ff;
  2377. s->comp_reg |= 0xff00 & (value << 8);
  2378. return;
  2379. default:
  2380. OMAP_BAD_REG(addr);
  2381. return;
  2382. }
  2383. }
  2384. static const MemoryRegionOps omap_rtc_ops = {
  2385. .read = omap_rtc_read,
  2386. .write = omap_rtc_write,
  2387. .endianness = DEVICE_NATIVE_ENDIAN,
  2388. };
  2389. static void omap_rtc_tick(void *opaque)
  2390. {
  2391. struct omap_rtc_s *s = opaque;
  2392. if (s->round) {
  2393. /* Round to nearest full minute. */
  2394. if (s->current_tm.tm_sec < 30)
  2395. s->ti -= s->current_tm.tm_sec;
  2396. else
  2397. s->ti += 60 - s->current_tm.tm_sec;
  2398. s->round = 0;
  2399. }
  2400. memcpy(&s->current_tm, localtime(&s->ti), sizeof(s->current_tm));
  2401. if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
  2402. s->status |= 0x40;
  2403. omap_rtc_interrupts_update(s);
  2404. }
  2405. if (s->interrupts & 0x04)
  2406. switch (s->interrupts & 3) {
  2407. case 0:
  2408. s->status |= 0x04;
  2409. qemu_irq_pulse(s->irq);
  2410. break;
  2411. case 1:
  2412. if (s->current_tm.tm_sec)
  2413. break;
  2414. s->status |= 0x08;
  2415. qemu_irq_pulse(s->irq);
  2416. break;
  2417. case 2:
  2418. if (s->current_tm.tm_sec || s->current_tm.tm_min)
  2419. break;
  2420. s->status |= 0x10;
  2421. qemu_irq_pulse(s->irq);
  2422. break;
  2423. case 3:
  2424. if (s->current_tm.tm_sec ||
  2425. s->current_tm.tm_min || s->current_tm.tm_hour)
  2426. break;
  2427. s->status |= 0x20;
  2428. qemu_irq_pulse(s->irq);
  2429. break;
  2430. }
  2431. /* Move on */
  2432. if (s->running)
  2433. s->ti ++;
  2434. s->tick += 1000;
  2435. /*
  2436. * Every full hour add a rough approximation of the compensation
  2437. * register to the 32kHz Timer (which drives the RTC) value.
  2438. */
  2439. if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
  2440. s->tick += s->comp_reg * 1000 / 32768;
  2441. qemu_mod_timer(s->clk, s->tick);
  2442. }
  2443. static void omap_rtc_reset(struct omap_rtc_s *s)
  2444. {
  2445. struct tm tm;
  2446. s->interrupts = 0;
  2447. s->comp_reg = 0;
  2448. s->running = 0;
  2449. s->pm_am = 0;
  2450. s->auto_comp = 0;
  2451. s->round = 0;
  2452. s->tick = qemu_get_clock_ms(rtc_clock);
  2453. memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
  2454. s->alarm_tm.tm_mday = 0x01;
  2455. s->status = 1 << 7;
  2456. qemu_get_timedate(&tm, 0);
  2457. s->ti = mktimegm(&tm);
  2458. omap_rtc_alarm_update(s);
  2459. omap_rtc_tick(s);
  2460. }
  2461. static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
  2462. target_phys_addr_t base,
  2463. qemu_irq timerirq, qemu_irq alarmirq,
  2464. omap_clk clk)
  2465. {
  2466. struct omap_rtc_s *s = (struct omap_rtc_s *)
  2467. g_malloc0(sizeof(struct omap_rtc_s));
  2468. s->irq = timerirq;
  2469. s->alarm = alarmirq;
  2470. s->clk = qemu_new_timer_ms(rtc_clock, omap_rtc_tick, s);
  2471. omap_rtc_reset(s);
  2472. memory_region_init_io(&s->iomem, &omap_rtc_ops, s,
  2473. "omap-rtc", 0x800);
  2474. memory_region_add_subregion(system_memory, base, &s->iomem);
  2475. return s;
  2476. }
  2477. /* Multi-channel Buffered Serial Port interfaces */
  2478. struct omap_mcbsp_s {
  2479. MemoryRegion iomem;
  2480. qemu_irq txirq;
  2481. qemu_irq rxirq;
  2482. qemu_irq txdrq;
  2483. qemu_irq rxdrq;
  2484. uint16_t spcr[2];
  2485. uint16_t rcr[2];
  2486. uint16_t xcr[2];
  2487. uint16_t srgr[2];
  2488. uint16_t mcr[2];
  2489. uint16_t pcr;
  2490. uint16_t rcer[8];
  2491. uint16_t xcer[8];
  2492. int tx_rate;
  2493. int rx_rate;
  2494. int tx_req;
  2495. int rx_req;
  2496. I2SCodec *codec;
  2497. QEMUTimer *source_timer;
  2498. QEMUTimer *sink_timer;
  2499. };
  2500. static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
  2501. {
  2502. int irq;
  2503. switch ((s->spcr[0] >> 4) & 3) { /* RINTM */
  2504. case 0:
  2505. irq = (s->spcr[0] >> 1) & 1; /* RRDY */
  2506. break;
  2507. case 3:
  2508. irq = (s->spcr[0] >> 3) & 1; /* RSYNCERR */
  2509. break;
  2510. default:
  2511. irq = 0;
  2512. break;
  2513. }
  2514. if (irq)
  2515. qemu_irq_pulse(s->rxirq);
  2516. switch ((s->spcr[1] >> 4) & 3) { /* XINTM */
  2517. case 0:
  2518. irq = (s->spcr[1] >> 1) & 1; /* XRDY */
  2519. break;
  2520. case 3:
  2521. irq = (s->spcr[1] >> 3) & 1; /* XSYNCERR */
  2522. break;
  2523. default:
  2524. irq = 0;
  2525. break;
  2526. }
  2527. if (irq)
  2528. qemu_irq_pulse(s->txirq);
  2529. }
  2530. static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
  2531. {
  2532. if ((s->spcr[0] >> 1) & 1) /* RRDY */
  2533. s->spcr[0] |= 1 << 2; /* RFULL */
  2534. s->spcr[0] |= 1 << 1; /* RRDY */
  2535. qemu_irq_raise(s->rxdrq);
  2536. omap_mcbsp_intr_update(s);
  2537. }
  2538. static void omap_mcbsp_source_tick(void *opaque)
  2539. {
  2540. struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
  2541. static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
  2542. if (!s->rx_rate)
  2543. return;
  2544. if (s->rx_req)
  2545. printf("%s: Rx FIFO overrun\n", __FUNCTION__);
  2546. s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
  2547. omap_mcbsp_rx_newdata(s);
  2548. qemu_mod_timer(s->source_timer, qemu_get_clock_ns(vm_clock) +
  2549. get_ticks_per_sec());
  2550. }
  2551. static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
  2552. {
  2553. if (!s->codec || !s->codec->rts)
  2554. omap_mcbsp_source_tick(s);
  2555. else if (s->codec->in.len) {
  2556. s->rx_req = s->codec->in.len;
  2557. omap_mcbsp_rx_newdata(s);
  2558. }
  2559. }
  2560. static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
  2561. {
  2562. qemu_del_timer(s->source_timer);
  2563. }
  2564. static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
  2565. {
  2566. s->spcr[0] &= ~(1 << 1); /* RRDY */
  2567. qemu_irq_lower(s->rxdrq);
  2568. omap_mcbsp_intr_update(s);
  2569. }
  2570. static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
  2571. {
  2572. s->spcr[1] |= 1 << 1; /* XRDY */
  2573. qemu_irq_raise(s->txdrq);
  2574. omap_mcbsp_intr_update(s);
  2575. }
  2576. static void omap_mcbsp_sink_tick(void *opaque)
  2577. {
  2578. struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
  2579. static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
  2580. if (!s->tx_rate)
  2581. return;
  2582. if (s->tx_req)
  2583. printf("%s: Tx FIFO underrun\n", __FUNCTION__);
  2584. s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
  2585. omap_mcbsp_tx_newdata(s);
  2586. qemu_mod_timer(s->sink_timer, qemu_get_clock_ns(vm_clock) +
  2587. get_ticks_per_sec());
  2588. }
  2589. static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
  2590. {
  2591. if (!s->codec || !s->codec->cts)
  2592. omap_mcbsp_sink_tick(s);
  2593. else if (s->codec->out.size) {
  2594. s->tx_req = s->codec->out.size;
  2595. omap_mcbsp_tx_newdata(s);
  2596. }
  2597. }
  2598. static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
  2599. {
  2600. s->spcr[1] &= ~(1 << 1); /* XRDY */
  2601. qemu_irq_lower(s->txdrq);
  2602. omap_mcbsp_intr_update(s);
  2603. if (s->codec && s->codec->cts)
  2604. s->codec->tx_swallow(s->codec->opaque);
  2605. }
  2606. static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
  2607. {
  2608. s->tx_req = 0;
  2609. omap_mcbsp_tx_done(s);
  2610. qemu_del_timer(s->sink_timer);
  2611. }
  2612. static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
  2613. {
  2614. int prev_rx_rate, prev_tx_rate;
  2615. int rx_rate = 0, tx_rate = 0;
  2616. int cpu_rate = 1500000; /* XXX */
  2617. /* TODO: check CLKSTP bit */
  2618. if (s->spcr[1] & (1 << 6)) { /* GRST */
  2619. if (s->spcr[0] & (1 << 0)) { /* RRST */
  2620. if ((s->srgr[1] & (1 << 13)) && /* CLKSM */
  2621. (s->pcr & (1 << 8))) { /* CLKRM */
  2622. if (~s->pcr & (1 << 7)) /* SCLKME */
  2623. rx_rate = cpu_rate /
  2624. ((s->srgr[0] & 0xff) + 1); /* CLKGDV */
  2625. } else
  2626. if (s->codec)
  2627. rx_rate = s->codec->rx_rate;
  2628. }
  2629. if (s->spcr[1] & (1 << 0)) { /* XRST */
  2630. if ((s->srgr[1] & (1 << 13)) && /* CLKSM */
  2631. (s->pcr & (1 << 9))) { /* CLKXM */
  2632. if (~s->pcr & (1 << 7)) /* SCLKME */
  2633. tx_rate = cpu_rate /
  2634. ((s->srgr[0] & 0xff) + 1); /* CLKGDV */
  2635. } else
  2636. if (s->codec)
  2637. tx_rate = s->codec->tx_rate;
  2638. }
  2639. }
  2640. prev_tx_rate = s->tx_rate;
  2641. prev_rx_rate = s->rx_rate;
  2642. s->tx_rate = tx_rate;
  2643. s->rx_rate = rx_rate;
  2644. if (s->codec)
  2645. s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
  2646. if (!prev_tx_rate && tx_rate)
  2647. omap_mcbsp_tx_start(s);
  2648. else if (s->tx_rate && !tx_rate)
  2649. omap_mcbsp_tx_stop(s);
  2650. if (!prev_rx_rate && rx_rate)
  2651. omap_mcbsp_rx_start(s);
  2652. else if (prev_tx_rate && !tx_rate)
  2653. omap_mcbsp_rx_stop(s);
  2654. }
  2655. static uint64_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr,
  2656. unsigned size)
  2657. {
  2658. struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
  2659. int offset = addr & OMAP_MPUI_REG_MASK;
  2660. uint16_t ret;
  2661. if (size != 2) {
  2662. return omap_badwidth_read16(opaque, addr);
  2663. }
  2664. switch (offset) {
  2665. case 0x00: /* DRR2 */
  2666. if (((s->rcr[0] >> 5) & 7) < 3) /* RWDLEN1 */
  2667. return 0x0000;
  2668. /* Fall through. */
  2669. case 0x02: /* DRR1 */
  2670. if (s->rx_req < 2) {
  2671. printf("%s: Rx FIFO underrun\n", __FUNCTION__);
  2672. omap_mcbsp_rx_done(s);
  2673. } else {
  2674. s->tx_req -= 2;
  2675. if (s->codec && s->codec->in.len >= 2) {
  2676. ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
  2677. ret |= s->codec->in.fifo[s->codec->in.start ++];
  2678. s->codec->in.len -= 2;
  2679. } else
  2680. ret = 0x0000;
  2681. if (!s->tx_req)
  2682. omap_mcbsp_rx_done(s);
  2683. return ret;
  2684. }
  2685. return 0x0000;
  2686. case 0x04: /* DXR2 */
  2687. case 0x06: /* DXR1 */
  2688. return 0x0000;
  2689. case 0x08: /* SPCR2 */
  2690. return s->spcr[1];
  2691. case 0x0a: /* SPCR1 */
  2692. return s->spcr[0];
  2693. case 0x0c: /* RCR2 */
  2694. return s->rcr[1];
  2695. case 0x0e: /* RCR1 */
  2696. return s->rcr[0];
  2697. case 0x10: /* XCR2 */
  2698. return s->xcr[1];
  2699. case 0x12: /* XCR1 */
  2700. return s->xcr[0];
  2701. case 0x14: /* SRGR2 */
  2702. return s->srgr[1];
  2703. case 0x16: /* SRGR1 */
  2704. return s->srgr[0];
  2705. case 0x18: /* MCR2 */
  2706. return s->mcr[1];
  2707. case 0x1a: /* MCR1 */
  2708. return s->mcr[0];
  2709. case 0x1c: /* RCERA */
  2710. return s->rcer[0];
  2711. case 0x1e: /* RCERB */
  2712. return s->rcer[1];
  2713. case 0x20: /* XCERA */
  2714. return s->xcer[0];
  2715. case 0x22: /* XCERB */
  2716. return s->xcer[1];
  2717. case 0x24: /* PCR0 */
  2718. return s->pcr;
  2719. case 0x26: /* RCERC */
  2720. return s->rcer[2];
  2721. case 0x28: /* RCERD */
  2722. return s->rcer[3];
  2723. case 0x2a: /* XCERC */
  2724. return s->xcer[2];
  2725. case 0x2c: /* XCERD */
  2726. return s->xcer[3];
  2727. case 0x2e: /* RCERE */
  2728. return s->rcer[4];
  2729. case 0x30: /* RCERF */
  2730. return s->rcer[5];
  2731. case 0x32: /* XCERE */
  2732. return s->xcer[4];
  2733. case 0x34: /* XCERF */
  2734. return s->xcer[5];
  2735. case 0x36: /* RCERG */
  2736. return s->rcer[6];
  2737. case 0x38: /* RCERH */
  2738. return s->rcer[7];
  2739. case 0x3a: /* XCERG */
  2740. return s->xcer[6];
  2741. case 0x3c: /* XCERH */
  2742. return s->xcer[7];
  2743. }
  2744. OMAP_BAD_REG(addr);
  2745. return 0;
  2746. }
  2747. static void omap_mcbsp_writeh(void *opaque, target_phys_addr_t addr,
  2748. uint32_t value)
  2749. {
  2750. struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
  2751. int offset = addr & OMAP_MPUI_REG_MASK;
  2752. switch (offset) {
  2753. case 0x00: /* DRR2 */
  2754. case 0x02: /* DRR1 */
  2755. OMAP_RO_REG(addr);
  2756. return;
  2757. case 0x04: /* DXR2 */
  2758. if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */
  2759. return;
  2760. /* Fall through. */
  2761. case 0x06: /* DXR1 */
  2762. if (s->tx_req > 1) {
  2763. s->tx_req -= 2;
  2764. if (s->codec && s->codec->cts) {
  2765. s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
  2766. s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
  2767. }
  2768. if (s->tx_req < 2)
  2769. omap_mcbsp_tx_done(s);
  2770. } else
  2771. printf("%s: Tx FIFO overrun\n", __FUNCTION__);
  2772. return;
  2773. case 0x08: /* SPCR2 */
  2774. s->spcr[1] &= 0x0002;
  2775. s->spcr[1] |= 0x03f9 & value;
  2776. s->spcr[1] |= 0x0004 & (value << 2); /* XEMPTY := XRST */
  2777. if (~value & 1) /* XRST */
  2778. s->spcr[1] &= ~6;
  2779. omap_mcbsp_req_update(s);
  2780. return;
  2781. case 0x0a: /* SPCR1 */
  2782. s->spcr[0] &= 0x0006;
  2783. s->spcr[0] |= 0xf8f9 & value;
  2784. if (value & (1 << 15)) /* DLB */
  2785. printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
  2786. if (~value & 1) { /* RRST */
  2787. s->spcr[0] &= ~6;
  2788. s->rx_req = 0;
  2789. omap_mcbsp_rx_done(s);
  2790. }
  2791. omap_mcbsp_req_update(s);
  2792. return;
  2793. case 0x0c: /* RCR2 */
  2794. s->rcr[1] = value & 0xffff;
  2795. return;
  2796. case 0x0e: /* RCR1 */
  2797. s->rcr[0] = value & 0x7fe0;
  2798. return;
  2799. case 0x10: /* XCR2 */
  2800. s->xcr[1] = value & 0xffff;
  2801. return;
  2802. case 0x12: /* XCR1 */
  2803. s->xcr[0] = value & 0x7fe0;
  2804. return;
  2805. case 0x14: /* SRGR2 */
  2806. s->srgr[1] = value & 0xffff;
  2807. omap_mcbsp_req_update(s);
  2808. return;
  2809. case 0x16: /* SRGR1 */
  2810. s->srgr[0] = value & 0xffff;
  2811. omap_mcbsp_req_update(s);
  2812. return;
  2813. case 0x18: /* MCR2 */
  2814. s->mcr[1] = value & 0x03e3;
  2815. if (value & 3) /* XMCM */
  2816. printf("%s: Tx channel selection mode enable attempt\n",
  2817. __FUNCTION__);
  2818. return;
  2819. case 0x1a: /* MCR1 */
  2820. s->mcr[0] = value & 0x03e1;
  2821. if (value & 1) /* RMCM */
  2822. printf("%s: Rx channel selection mode enable attempt\n",
  2823. __FUNCTION__);
  2824. return;
  2825. case 0x1c: /* RCERA */
  2826. s->rcer[0] = value & 0xffff;
  2827. return;
  2828. case 0x1e: /* RCERB */
  2829. s->rcer[1] = value & 0xffff;
  2830. return;
  2831. case 0x20: /* XCERA */
  2832. s->xcer[0] = value & 0xffff;
  2833. return;
  2834. case 0x22: /* XCERB */
  2835. s->xcer[1] = value & 0xffff;
  2836. return;
  2837. case 0x24: /* PCR0 */
  2838. s->pcr = value & 0x7faf;
  2839. return;
  2840. case 0x26: /* RCERC */
  2841. s->rcer[2] = value & 0xffff;
  2842. return;
  2843. case 0x28: /* RCERD */
  2844. s->rcer[3] = value & 0xffff;
  2845. return;
  2846. case 0x2a: /* XCERC */
  2847. s->xcer[2] = value & 0xffff;
  2848. return;
  2849. case 0x2c: /* XCERD */
  2850. s->xcer[3] = value & 0xffff;
  2851. return;
  2852. case 0x2e: /* RCERE */
  2853. s->rcer[4] = value & 0xffff;
  2854. return;
  2855. case 0x30: /* RCERF */
  2856. s->rcer[5] = value & 0xffff;
  2857. return;
  2858. case 0x32: /* XCERE */
  2859. s->xcer[4] = value & 0xffff;
  2860. return;
  2861. case 0x34: /* XCERF */
  2862. s->xcer[5] = value & 0xffff;
  2863. return;
  2864. case 0x36: /* RCERG */
  2865. s->rcer[6] = value & 0xffff;
  2866. return;
  2867. case 0x38: /* RCERH */
  2868. s->rcer[7] = value & 0xffff;
  2869. return;
  2870. case 0x3a: /* XCERG */
  2871. s->xcer[6] = value & 0xffff;
  2872. return;
  2873. case 0x3c: /* XCERH */
  2874. s->xcer[7] = value & 0xffff;
  2875. return;
  2876. }
  2877. OMAP_BAD_REG(addr);
  2878. }
  2879. static void omap_mcbsp_writew(void *opaque, target_phys_addr_t addr,
  2880. uint32_t value)
  2881. {
  2882. struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
  2883. int offset = addr & OMAP_MPUI_REG_MASK;
  2884. if (offset == 0x04) { /* DXR */
  2885. if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */
  2886. return;
  2887. if (s->tx_req > 3) {
  2888. s->tx_req -= 4;
  2889. if (s->codec && s->codec->cts) {
  2890. s->codec->out.fifo[s->codec->out.len ++] =
  2891. (value >> 24) & 0xff;
  2892. s->codec->out.fifo[s->codec->out.len ++] =
  2893. (value >> 16) & 0xff;
  2894. s->codec->out.fifo[s->codec->out.len ++] =
  2895. (value >> 8) & 0xff;
  2896. s->codec->out.fifo[s->codec->out.len ++] =
  2897. (value >> 0) & 0xff;
  2898. }
  2899. if (s->tx_req < 4)
  2900. omap_mcbsp_tx_done(s);
  2901. } else
  2902. printf("%s: Tx FIFO overrun\n", __FUNCTION__);
  2903. return;
  2904. }
  2905. omap_badwidth_write16(opaque, addr, value);
  2906. }
  2907. static void omap_mcbsp_write(void *opaque, target_phys_addr_t addr,
  2908. uint64_t value, unsigned size)
  2909. {
  2910. switch (size) {
  2911. case 2: return omap_mcbsp_writeh(opaque, addr, value);
  2912. case 4: return omap_mcbsp_writew(opaque, addr, value);
  2913. default: return omap_badwidth_write16(opaque, addr, value);
  2914. }
  2915. }
  2916. static const MemoryRegionOps omap_mcbsp_ops = {
  2917. .read = omap_mcbsp_read,
  2918. .write = omap_mcbsp_write,
  2919. .endianness = DEVICE_NATIVE_ENDIAN,
  2920. };
  2921. static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
  2922. {
  2923. memset(&s->spcr, 0, sizeof(s->spcr));
  2924. memset(&s->rcr, 0, sizeof(s->rcr));
  2925. memset(&s->xcr, 0, sizeof(s->xcr));
  2926. s->srgr[0] = 0x0001;
  2927. s->srgr[1] = 0x2000;
  2928. memset(&s->mcr, 0, sizeof(s->mcr));
  2929. memset(&s->pcr, 0, sizeof(s->pcr));
  2930. memset(&s->rcer, 0, sizeof(s->rcer));
  2931. memset(&s->xcer, 0, sizeof(s->xcer));
  2932. s->tx_req = 0;
  2933. s->rx_req = 0;
  2934. s->tx_rate = 0;
  2935. s->rx_rate = 0;
  2936. qemu_del_timer(s->source_timer);
  2937. qemu_del_timer(s->sink_timer);
  2938. }
  2939. static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
  2940. target_phys_addr_t base,
  2941. qemu_irq txirq, qemu_irq rxirq,
  2942. qemu_irq *dma, omap_clk clk)
  2943. {
  2944. struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
  2945. g_malloc0(sizeof(struct omap_mcbsp_s));
  2946. s->txirq = txirq;
  2947. s->rxirq = rxirq;
  2948. s->txdrq = dma[0];
  2949. s->rxdrq = dma[1];
  2950. s->sink_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_sink_tick, s);
  2951. s->source_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_source_tick, s);
  2952. omap_mcbsp_reset(s);
  2953. memory_region_init_io(&s->iomem, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
  2954. memory_region_add_subregion(system_memory, base, &s->iomem);
  2955. return s;
  2956. }
  2957. static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
  2958. {
  2959. struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
  2960. if (s->rx_rate) {
  2961. s->rx_req = s->codec->in.len;
  2962. omap_mcbsp_rx_newdata(s);
  2963. }
  2964. }
  2965. static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
  2966. {
  2967. struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
  2968. if (s->tx_rate) {
  2969. s->tx_req = s->codec->out.size;
  2970. omap_mcbsp_tx_newdata(s);
  2971. }
  2972. }
  2973. void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
  2974. {
  2975. s->codec = slave;
  2976. slave->rx_swallow = qemu_allocate_irqs(omap_mcbsp_i2s_swallow, s, 1)[0];
  2977. slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
  2978. }
  2979. /* LED Pulse Generators */
  2980. struct omap_lpg_s {
  2981. MemoryRegion iomem;
  2982. QEMUTimer *tm;
  2983. uint8_t control;
  2984. uint8_t power;
  2985. int64_t on;
  2986. int64_t period;
  2987. int clk;
  2988. int cycle;
  2989. };
  2990. static void omap_lpg_tick(void *opaque)
  2991. {
  2992. struct omap_lpg_s *s = opaque;
  2993. if (s->cycle)
  2994. qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->period - s->on);
  2995. else
  2996. qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->on);
  2997. s->cycle = !s->cycle;
  2998. printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
  2999. }
  3000. static void omap_lpg_update(struct omap_lpg_s *s)
  3001. {
  3002. int64_t on, period = 1, ticks = 1000;
  3003. static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
  3004. if (~s->control & (1 << 6)) /* LPGRES */
  3005. on = 0;
  3006. else if (s->control & (1 << 7)) /* PERM_ON */
  3007. on = period;
  3008. else {
  3009. period = muldiv64(ticks, per[s->control & 7], /* PERCTRL */
  3010. 256 / 32);
  3011. on = (s->clk && s->power) ? muldiv64(ticks,
  3012. per[(s->control >> 3) & 7], 256) : 0; /* ONCTRL */
  3013. }
  3014. qemu_del_timer(s->tm);
  3015. if (on == period && s->on < s->period)
  3016. printf("%s: LED is on\n", __FUNCTION__);
  3017. else if (on == 0 && s->on)
  3018. printf("%s: LED is off\n", __FUNCTION__);
  3019. else if (on && (on != s->on || period != s->period)) {
  3020. s->cycle = 0;
  3021. s->on = on;
  3022. s->period = period;
  3023. omap_lpg_tick(s);
  3024. return;
  3025. }
  3026. s->on = on;
  3027. s->period = period;
  3028. }
  3029. static void omap_lpg_reset(struct omap_lpg_s *s)
  3030. {
  3031. s->control = 0x00;
  3032. s->power = 0x00;
  3033. s->clk = 1;
  3034. omap_lpg_update(s);
  3035. }
  3036. static uint64_t omap_lpg_read(void *opaque, target_phys_addr_t addr,
  3037. unsigned size)
  3038. {
  3039. struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
  3040. int offset = addr & OMAP_MPUI_REG_MASK;
  3041. if (size != 1) {
  3042. return omap_badwidth_read8(opaque, addr);
  3043. }
  3044. switch (offset) {
  3045. case 0x00: /* LCR */
  3046. return s->control;
  3047. case 0x04: /* PMR */
  3048. return s->power;
  3049. }
  3050. OMAP_BAD_REG(addr);
  3051. return 0;
  3052. }
  3053. static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
  3054. uint64_t value, unsigned size)
  3055. {
  3056. struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
  3057. int offset = addr & OMAP_MPUI_REG_MASK;
  3058. if (size != 1) {
  3059. return omap_badwidth_write8(opaque, addr, value);
  3060. }
  3061. switch (offset) {
  3062. case 0x00: /* LCR */
  3063. if (~value & (1 << 6)) /* LPGRES */
  3064. omap_lpg_reset(s);
  3065. s->control = value & 0xff;
  3066. omap_lpg_update(s);
  3067. return;
  3068. case 0x04: /* PMR */
  3069. s->power = value & 0x01;
  3070. omap_lpg_update(s);
  3071. return;
  3072. default:
  3073. OMAP_BAD_REG(addr);
  3074. return;
  3075. }
  3076. }
  3077. static const MemoryRegionOps omap_lpg_ops = {
  3078. .read = omap_lpg_read,
  3079. .write = omap_lpg_write,
  3080. .endianness = DEVICE_NATIVE_ENDIAN,
  3081. };
  3082. static void omap_lpg_clk_update(void *opaque, int line, int on)
  3083. {
  3084. struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
  3085. s->clk = on;
  3086. omap_lpg_update(s);
  3087. }
  3088. static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
  3089. target_phys_addr_t base, omap_clk clk)
  3090. {
  3091. struct omap_lpg_s *s = (struct omap_lpg_s *)
  3092. g_malloc0(sizeof(struct omap_lpg_s));
  3093. s->tm = qemu_new_timer_ms(vm_clock, omap_lpg_tick, s);
  3094. omap_lpg_reset(s);
  3095. memory_region_init_io(&s->iomem, &omap_lpg_ops, s, "omap-lpg", 0x800);
  3096. memory_region_add_subregion(system_memory, base, &s->iomem);
  3097. omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
  3098. return s;
  3099. }
  3100. /* MPUI Peripheral Bridge configuration */
  3101. static uint64_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr,
  3102. unsigned size)
  3103. {
  3104. if (size != 2) {
  3105. return omap_badwidth_read16(opaque, addr);
  3106. }
  3107. if (addr == OMAP_MPUI_BASE) /* CMR */
  3108. return 0xfe4d;
  3109. OMAP_BAD_REG(addr);
  3110. return 0;
  3111. }
  3112. static void omap_mpui_io_write(void *opaque, target_phys_addr_t addr,
  3113. uint64_t value, unsigned size)
  3114. {
  3115. /* FIXME: infinite loop */
  3116. omap_badwidth_write16(opaque, addr, value);
  3117. }
  3118. static const MemoryRegionOps omap_mpui_io_ops = {
  3119. .read = omap_mpui_io_read,
  3120. .write = omap_mpui_io_write,
  3121. .endianness = DEVICE_NATIVE_ENDIAN,
  3122. };
  3123. static void omap_setup_mpui_io(MemoryRegion *system_memory,
  3124. struct omap_mpu_state_s *mpu)
  3125. {
  3126. memory_region_init_io(&mpu->mpui_io_iomem, &omap_mpui_io_ops, mpu,
  3127. "omap-mpui-io", 0x7fff);
  3128. memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
  3129. &mpu->mpui_io_iomem);
  3130. }
  3131. /* General chip reset */
  3132. static void omap1_mpu_reset(void *opaque)
  3133. {
  3134. struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
  3135. omap_dma_reset(mpu->dma);
  3136. omap_mpu_timer_reset(mpu->timer[0]);
  3137. omap_mpu_timer_reset(mpu->timer[1]);
  3138. omap_mpu_timer_reset(mpu->timer[2]);
  3139. omap_wd_timer_reset(mpu->wdt);
  3140. omap_os_timer_reset(mpu->os_timer);
  3141. omap_lcdc_reset(mpu->lcd);
  3142. omap_ulpd_pm_reset(mpu);
  3143. omap_pin_cfg_reset(mpu);
  3144. omap_mpui_reset(mpu);
  3145. omap_tipb_bridge_reset(mpu->private_tipb);
  3146. omap_tipb_bridge_reset(mpu->public_tipb);
  3147. omap_dpll_reset(mpu->dpll[0]);
  3148. omap_dpll_reset(mpu->dpll[1]);
  3149. omap_dpll_reset(mpu->dpll[2]);
  3150. omap_uart_reset(mpu->uart[0]);
  3151. omap_uart_reset(mpu->uart[1]);
  3152. omap_uart_reset(mpu->uart[2]);
  3153. omap_mmc_reset(mpu->mmc);
  3154. omap_mpuio_reset(mpu->mpuio);
  3155. omap_uwire_reset(mpu->microwire);
  3156. omap_pwl_reset(mpu->pwl);
  3157. omap_pwt_reset(mpu->pwt);
  3158. omap_rtc_reset(mpu->rtc);
  3159. omap_mcbsp_reset(mpu->mcbsp1);
  3160. omap_mcbsp_reset(mpu->mcbsp2);
  3161. omap_mcbsp_reset(mpu->mcbsp3);
  3162. omap_lpg_reset(mpu->led[0]);
  3163. omap_lpg_reset(mpu->led[1]);
  3164. omap_clkm_reset(mpu);
  3165. cpu_reset(CPU(mpu->cpu));
  3166. }
  3167. static const struct omap_map_s {
  3168. target_phys_addr_t phys_dsp;
  3169. target_phys_addr_t phys_mpu;
  3170. uint32_t size;
  3171. const char *name;
  3172. } omap15xx_dsp_mm[] = {
  3173. /* Strobe 0 */
  3174. { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" }, /* CS0 */
  3175. { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" }, /* CS1 */
  3176. { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" }, /* CS3 */
  3177. { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" }, /* CS4 */
  3178. { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" }, /* CS5 */
  3179. { 0xe1013000, 0xfffb3000, 0x800, "uWire" }, /* CS6 */
  3180. { 0xe1013800, 0xfffb3800, 0x800, "I^2C" }, /* CS7 */
  3181. { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" }, /* CS8 */
  3182. { 0xe1014800, 0xfffb4800, 0x800, "RTC" }, /* CS9 */
  3183. { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" }, /* CS10 */
  3184. { 0xe1015800, 0xfffb5800, 0x800, "PWL" }, /* CS11 */
  3185. { 0xe1016000, 0xfffb6000, 0x800, "PWT" }, /* CS12 */
  3186. { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" }, /* CS14 */
  3187. { 0xe1017800, 0xfffb7800, 0x800, "MMC" }, /* CS15 */
  3188. { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" }, /* CS18 */
  3189. { 0xe1019800, 0xfffb9800, 0x800, "UART3" }, /* CS19 */
  3190. { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" }, /* CS25 */
  3191. /* Strobe 1 */
  3192. { 0xe101e000, 0xfffce000, 0x800, "GPIOs" }, /* CS28 */
  3193. { 0 }
  3194. };
  3195. static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
  3196. const struct omap_map_s *map)
  3197. {
  3198. MemoryRegion *io;
  3199. for (; map->phys_dsp; map ++) {
  3200. io = g_new(MemoryRegion, 1);
  3201. memory_region_init_alias(io, map->name,
  3202. system_memory, map->phys_mpu, map->size);
  3203. memory_region_add_subregion(system_memory, map->phys_dsp, io);
  3204. }
  3205. }
  3206. void omap_mpu_wakeup(void *opaque, int irq, int req)
  3207. {
  3208. struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
  3209. if (mpu->cpu->env.halted) {
  3210. cpu_interrupt(&mpu->cpu->env, CPU_INTERRUPT_EXITTB);
  3211. }
  3212. }
  3213. static const struct dma_irq_map omap1_dma_irq_map[] = {
  3214. { 0, OMAP_INT_DMA_CH0_6 },
  3215. { 0, OMAP_INT_DMA_CH1_7 },
  3216. { 0, OMAP_INT_DMA_CH2_8 },
  3217. { 0, OMAP_INT_DMA_CH3 },
  3218. { 0, OMAP_INT_DMA_CH4 },
  3219. { 0, OMAP_INT_DMA_CH5 },
  3220. { 1, OMAP_INT_1610_DMA_CH6 },
  3221. { 1, OMAP_INT_1610_DMA_CH7 },
  3222. { 1, OMAP_INT_1610_DMA_CH8 },
  3223. { 1, OMAP_INT_1610_DMA_CH9 },
  3224. { 1, OMAP_INT_1610_DMA_CH10 },
  3225. { 1, OMAP_INT_1610_DMA_CH11 },
  3226. { 1, OMAP_INT_1610_DMA_CH12 },
  3227. { 1, OMAP_INT_1610_DMA_CH13 },
  3228. { 1, OMAP_INT_1610_DMA_CH14 },
  3229. { 1, OMAP_INT_1610_DMA_CH15 }
  3230. };
  3231. /* DMA ports for OMAP1 */
  3232. static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
  3233. target_phys_addr_t addr)
  3234. {
  3235. return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
  3236. }
  3237. static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
  3238. target_phys_addr_t addr)
  3239. {
  3240. return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
  3241. addr);
  3242. }
  3243. static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
  3244. target_phys_addr_t addr)
  3245. {
  3246. return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
  3247. }
  3248. static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
  3249. target_phys_addr_t addr)
  3250. {
  3251. return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
  3252. }
  3253. static int omap_validate_local_addr(struct omap_mpu_state_s *s,
  3254. target_phys_addr_t addr)
  3255. {
  3256. return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
  3257. }
  3258. static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
  3259. target_phys_addr_t addr)
  3260. {
  3261. return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
  3262. }
  3263. struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
  3264. unsigned long sdram_size,
  3265. const char *core)
  3266. {
  3267. int i;
  3268. struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
  3269. g_malloc0(sizeof(struct omap_mpu_state_s));
  3270. qemu_irq *cpu_irq;
  3271. qemu_irq dma_irqs[6];
  3272. DriveInfo *dinfo;
  3273. SysBusDevice *busdev;
  3274. if (!core)
  3275. core = "ti925t";
  3276. /* Core */
  3277. s->mpu_model = omap310;
  3278. s->cpu = cpu_arm_init(core);
  3279. if (s->cpu == NULL) {
  3280. fprintf(stderr, "Unable to find CPU definition\n");
  3281. exit(1);
  3282. }
  3283. s->sdram_size = sdram_size;
  3284. s->sram_size = OMAP15XX_SRAM_SIZE;
  3285. s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
  3286. /* Clocks */
  3287. omap_clk_init(s);
  3288. /* Memory-mapped stuff */
  3289. memory_region_init_ram(&s->emiff_ram, "omap1.dram", s->sdram_size);
  3290. vmstate_register_ram_global(&s->emiff_ram);
  3291. memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
  3292. memory_region_init_ram(&s->imif_ram, "omap1.sram", s->sram_size);
  3293. vmstate_register_ram_global(&s->imif_ram);
  3294. memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
  3295. omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
  3296. cpu_irq = arm_pic_init_cpu(s->cpu);
  3297. s->ih[0] = qdev_create(NULL, "omap-intc");
  3298. qdev_prop_set_uint32(s->ih[0], "size", 0x100);
  3299. qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
  3300. qdev_init_nofail(s->ih[0]);
  3301. busdev = sysbus_from_qdev(s->ih[0]);
  3302. sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
  3303. sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
  3304. sysbus_mmio_map(busdev, 0, 0xfffecb00);
  3305. s->ih[1] = qdev_create(NULL, "omap-intc");
  3306. qdev_prop_set_uint32(s->ih[1], "size", 0x800);
  3307. qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
  3308. qdev_init_nofail(s->ih[1]);
  3309. busdev = sysbus_from_qdev(s->ih[1]);
  3310. sysbus_connect_irq(busdev, 0,
  3311. qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ));
  3312. /* The second interrupt controller's FIQ output is not wired up */
  3313. sysbus_mmio_map(busdev, 0, 0xfffe0000);
  3314. for (i = 0; i < 6; i++) {
  3315. dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih],
  3316. omap1_dma_irq_map[i].intr);
  3317. }
  3318. s->dma = omap_dma_init(0xfffed800, dma_irqs, system_memory,
  3319. qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD),
  3320. s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
  3321. s->port[emiff ].addr_valid = omap_validate_emiff_addr;
  3322. s->port[emifs ].addr_valid = omap_validate_emifs_addr;
  3323. s->port[imif ].addr_valid = omap_validate_imif_addr;
  3324. s->port[tipb ].addr_valid = omap_validate_tipb_addr;
  3325. s->port[local ].addr_valid = omap_validate_local_addr;
  3326. s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
  3327. /* Register SDRAM and SRAM DMA ports for fast transfers. */
  3328. soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram),
  3329. OMAP_EMIFF_BASE, s->sdram_size);
  3330. soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
  3331. OMAP_IMIF_BASE, s->sram_size);
  3332. s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
  3333. qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1),
  3334. omap_findclk(s, "mputim_ck"));
  3335. s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
  3336. qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2),
  3337. omap_findclk(s, "mputim_ck"));
  3338. s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
  3339. qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3),
  3340. omap_findclk(s, "mputim_ck"));
  3341. s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
  3342. qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
  3343. omap_findclk(s, "armwdt_ck"));
  3344. s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
  3345. qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER),
  3346. omap_findclk(s, "clk32-kHz"));
  3347. s->lcd = omap_lcdc_init(system_memory, 0xfffec000,
  3348. qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL),
  3349. omap_dma_get_lcdch(s->dma),
  3350. omap_findclk(s, "lcd_ck"));
  3351. omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
  3352. omap_pin_cfg_init(system_memory, 0xfffe1000, s);
  3353. omap_id_init(system_memory, s);
  3354. omap_mpui_init(system_memory, 0xfffec900, s);
  3355. s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
  3356. qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV),
  3357. omap_findclk(s, "tipb_ck"));
  3358. s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
  3359. qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB),
  3360. omap_findclk(s, "tipb_ck"));
  3361. omap_tcmi_init(system_memory, 0xfffecc00, s);
  3362. s->uart[0] = omap_uart_init(0xfffb0000,
  3363. qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
  3364. omap_findclk(s, "uart1_ck"),
  3365. omap_findclk(s, "uart1_ck"),
  3366. s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
  3367. "uart1",
  3368. serial_hds[0]);
  3369. s->uart[1] = omap_uart_init(0xfffb0800,
  3370. qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
  3371. omap_findclk(s, "uart2_ck"),
  3372. omap_findclk(s, "uart2_ck"),
  3373. s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
  3374. "uart2",
  3375. serial_hds[0] ? serial_hds[1] : NULL);
  3376. s->uart[2] = omap_uart_init(0xfffb9800,
  3377. qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
  3378. omap_findclk(s, "uart3_ck"),
  3379. omap_findclk(s, "uart3_ck"),
  3380. s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
  3381. "uart3",
  3382. serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
  3383. s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
  3384. omap_findclk(s, "dpll1"));
  3385. s->dpll[1] = omap_dpll_init(system_memory, 0xfffed000,
  3386. omap_findclk(s, "dpll2"));
  3387. s->dpll[2] = omap_dpll_init(system_memory, 0xfffed100,
  3388. omap_findclk(s, "dpll3"));
  3389. dinfo = drive_get(IF_SD, 0, 0);
  3390. if (!dinfo) {
  3391. fprintf(stderr, "qemu: missing SecureDigital device\n");
  3392. exit(1);
  3393. }
  3394. s->mmc = omap_mmc_init(0xfffb7800, system_memory, dinfo->bdrv,
  3395. qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
  3396. &s->drq[OMAP_DMA_MMC_TX],
  3397. omap_findclk(s, "mmc_ck"));
  3398. s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000,
  3399. qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD),
  3400. qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO),
  3401. s->wakeup, omap_findclk(s, "clk32-kHz"));
  3402. s->gpio = qdev_create(NULL, "omap-gpio");
  3403. qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
  3404. qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck"));
  3405. qdev_init_nofail(s->gpio);
  3406. sysbus_connect_irq(sysbus_from_qdev(s->gpio), 0,
  3407. qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
  3408. sysbus_mmio_map(sysbus_from_qdev(s->gpio), 0, 0xfffce000);
  3409. s->microwire = omap_uwire_init(system_memory, 0xfffb3000,
  3410. qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX),
  3411. qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX),
  3412. s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
  3413. s->pwl = omap_pwl_init(system_memory, 0xfffb5800,
  3414. omap_findclk(s, "armxor_ck"));
  3415. s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
  3416. omap_findclk(s, "armxor_ck"));
  3417. s->i2c[0] = qdev_create(NULL, "omap_i2c");
  3418. qdev_prop_set_uint8(s->i2c[0], "revision", 0x11);
  3419. qdev_prop_set_ptr(s->i2c[0], "fclk", omap_findclk(s, "mpuper_ck"));
  3420. qdev_init_nofail(s->i2c[0]);
  3421. busdev = sysbus_from_qdev(s->i2c[0]);
  3422. sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C));
  3423. sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_I2C_TX]);
  3424. sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_I2C_RX]);
  3425. sysbus_mmio_map(busdev, 0, 0xfffb3800);
  3426. s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
  3427. qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),
  3428. qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM),
  3429. omap_findclk(s, "clk32-kHz"));
  3430. s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800,
  3431. qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX),
  3432. qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX),
  3433. &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
  3434. s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000,
  3435. qdev_get_gpio_in(s->ih[0],
  3436. OMAP_INT_310_McBSP2_TX),
  3437. qdev_get_gpio_in(s->ih[0],
  3438. OMAP_INT_310_McBSP2_RX),
  3439. &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
  3440. s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000,
  3441. qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX),
  3442. qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX),
  3443. &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
  3444. s->led[0] = omap_lpg_init(system_memory,
  3445. 0xfffbd000, omap_findclk(s, "clk32-kHz"));
  3446. s->led[1] = omap_lpg_init(system_memory,
  3447. 0xfffbd800, omap_findclk(s, "clk32-kHz"));
  3448. /* Register mappings not currenlty implemented:
  3449. * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310)
  3450. * MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310)
  3451. * USB W2FC fffb4000 - fffb47ff
  3452. * Camera Interface fffb6800 - fffb6fff
  3453. * USB Host fffba000 - fffba7ff
  3454. * FAC fffba800 - fffbafff
  3455. * HDQ/1-Wire fffbc000 - fffbc7ff
  3456. * TIPB switches fffbc800 - fffbcfff
  3457. * Mailbox fffcf000 - fffcf7ff
  3458. * Local bus IF fffec100 - fffec1ff
  3459. * Local bus MMU fffec200 - fffec2ff
  3460. * DSP MMU fffed200 - fffed2ff
  3461. */
  3462. omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
  3463. omap_setup_mpui_io(system_memory, s);
  3464. qemu_register_reset(omap1_mpu_reset, s);
  3465. return s;
  3466. }