2
0

screamer.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /*
  2. * QEMU PowerMac Awacs Screamer device support
  3. *
  4. * Copyright (c) 2016 Mark Cave-Ayland
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu/osdep.h"
  25. #include "audio/audio.h"
  26. #include "hw/hw.h"
  27. #include "hw/irq.h"
  28. #include "audio/audio.h"
  29. #include "hw/audio/screamer.h"
  30. #include "hw/qdev-properties.h"
  31. #include "qemu/timer.h"
  32. #include "hw/ppc/mac_dbdma.h"
  33. #include "system/system.h"
  34. #include "qemu/cutils.h"
  35. #include "qemu/log.h"
  36. #include "qemu/typedefs.h"
  37. /* debug screamer */
  38. //#define DEBUG_SCREAMER
  39. #ifdef DEBUG_SCREAMER
  40. #define SCREAMER_DPRINTF(fmt, ...) \
  41. do { printf("SCREAMER: " fmt , ## __VA_ARGS__); } while (0)
  42. #else
  43. #define SCREAMER_DPRINTF(fmt, ...)
  44. #endif
  45. /* chip registers */
  46. #define SND_CTRL_REG 0x0
  47. #define CODEC_CTRL_REG 0x1
  48. #define CODEC_STAT_REG 0x2
  49. #define CLIP_CNT_REG 0x3
  50. #define BYTE_SWAP_REG 0x4
  51. #define FRAME_CNT_REG 0x5
  52. #define CODEC_CTRL_MASKECMD (0x1 << 24)
  53. #define CODEC_CTRL1_RECALIBRATE 0x4
  54. #define CODEC_STAT_MANUFACTURER_CRYSTAL 0x100
  55. #define CODEC_STAT_AWACS_REVISION 0x3000
  56. #define CODEC_STAT_MASK_VALID (0x1 << 22)
  57. /* Audio */
  58. static const char *s_spk = "screamer";
  59. static void pmac_screamer_tx_transfer(ScreamerState *s)
  60. {
  61. DBDMA_io *io = &s->io;
  62. int samples;
  63. samples = MIN(io->len >> s->shift, s->samples - s->wpos);
  64. dma_memory_read(&address_space_memory, io->addr,
  65. &s->mixbuf[s->wpos << s->shift], samples << s->shift,
  66. MEMTXATTRS_UNSPECIFIED);
  67. SCREAMER_DPRINTF("DMA actually transferred 0x%x, wpos is %d\n", samples << s->shift, s->wpos);
  68. io->addr += (samples << s->shift);
  69. io->len -= (samples << s->shift);
  70. s->wpos += samples;
  71. /* Continue DBDMA if we have completed the transfer, otherwise defer */
  72. if (io->len == 0) {
  73. SCREAMER_DPRINTF("-> End of transfer\n");
  74. io->dma_end(io);
  75. }
  76. }
  77. static void pmac_screamer_tx(DBDMA_io *io)
  78. {
  79. ScreamerState *s = io->opaque;
  80. SCREAMER_DPRINTF("DMA TX transfer: addr %" HWADDR_PRIx
  81. " len: %x\n", io->addr, io->len);
  82. memcpy(&s->io, io, sizeof(DBDMA_io));
  83. //if (s->wpos + (s->io.len >> s->shift) > s->samples) {
  84. // return;
  85. //}
  86. pmac_screamer_tx_transfer(s);
  87. }
  88. static void pmac_screamer_tx_flush(DBDMA_io *io)
  89. {
  90. DBDMA_channel *ch = io->channel;
  91. dbdma_cmd *current = &ch->current;
  92. uint16_t cmd;
  93. SCREAMER_DPRINTF("DMA TX flush!\n");
  94. #if 0
  95. cmd = le16_to_cpu(current->command) & COMMAND_MASK;
  96. if (cmd == OUTPUT_MORE || cmd == OUTPUT_LAST ||
  97. cmd == INPUT_MORE || cmd == INPUT_LAST) {
  98. current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
  99. current->res_count = cpu_to_le16(io->len);
  100. dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
  101. &ch->current, sizeof(dbdma_cmd),
  102. MEMTXATTRS_UNSPECIFIED);
  103. }
  104. #endif
  105. ch->io.processing = false;
  106. cmd = le16_to_cpu(current->command) & COMMAND_MASK;
  107. if (cmd == INPUT_MORE || cmd == INPUT_LAST) {
  108. current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
  109. current->res_count = cpu_to_le16(io->len);
  110. dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
  111. &ch->current, sizeof(dbdma_cmd),
  112. MEMTXATTRS_UNSPECIFIED);
  113. }
  114. }
  115. static void pmac_screamer_rx(DBDMA_io *io)
  116. {
  117. SCREAMER_DPRINTF("DMA RX transfer: addr %" HWADDR_PRIx
  118. " len: %x\n", io->addr, io->len);
  119. //ScreamerState *s = io->opaque;
  120. DBDMA_channel *ch = io->channel;
  121. /* FIXME: stop channel after updating with status to stop MacOS 9 freezing */
  122. ch->regs[DBDMA_STATUS] &= ~RUN;
  123. io->dma_end(io);
  124. }
  125. static void pmac_screamer_rx_flush(DBDMA_io *io)
  126. {
  127. DBDMA_channel *ch = io->channel;
  128. dbdma_cmd *current = &ch->current;
  129. uint16_t cmd;
  130. SCREAMER_DPRINTF("DMA RX flush!\n");
  131. #if 1
  132. cmd = le16_to_cpu(current->command) & COMMAND_MASK;
  133. if (cmd == INPUT_MORE || cmd == INPUT_LAST) {
  134. current->xfer_status = cpu_to_le16(ch->regs[DBDMA_STATUS]);
  135. current->res_count = cpu_to_le16(io->len);
  136. dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO],
  137. &ch->current, sizeof(dbdma_cmd),
  138. MEMTXATTRS_UNSPECIFIED);
  139. }
  140. #endif
  141. }
  142. void macio_screamer_register_dma(ScreamerState *s, void *dbdma, int txchannel, int rxchannel)
  143. {
  144. s->dbdma = dbdma;
  145. DBDMA_register_channel(dbdma, txchannel, s->dma_tx_irq,
  146. pmac_screamer_tx, pmac_screamer_tx_flush, s);
  147. DBDMA_register_channel(dbdma, rxchannel, s->dma_rx_irq,
  148. pmac_screamer_rx, pmac_screamer_rx_flush, s);
  149. }
  150. static void screamerspk_callback(void *opaque, int free_b)
  151. {
  152. ScreamerState *s = opaque;
  153. DBDMA_io *io = &s->io;
  154. int samples, generated;
  155. if (free_b == 0) {
  156. return;
  157. }
  158. if (s->wpos - s->rpos == 0) {
  159. return;
  160. }
  161. samples = MIN(s->samples, free_b >> s->shift);
  162. generated = MIN(samples, s->wpos - s->rpos);
  163. AUD_write(s->voice, s->mixbuf + (uintptr_t)(s->rpos << s->shift),
  164. generated << s->shift);
  165. SCREAMER_DPRINTF(" - generated %d, wpos %d, rpos %d\n", generated, s->wpos, s->rpos);
  166. s->regs[FRAME_CNT_REG] += generated;
  167. s->rpos += generated;
  168. if (s->rpos < s->wpos) {
  169. return;
  170. }
  171. s->wpos = 0;
  172. s->rpos = 0;
  173. if (io->len) {
  174. DBDMA_channel *ch = io->channel;
  175. uint32_t status = ch->regs[DBDMA_STATUS];
  176. SCREAMER_DPRINTF("Continue deferred transfer\n");
  177. /* Disable channel so we only complete the current transfer */
  178. ch->regs[DBDMA_STATUS] &= ~RUN;
  179. /* Perform deferred transfer */
  180. pmac_screamer_tx_transfer(s);
  181. /* Re-enable channel */
  182. ch->regs[DBDMA_STATUS] = status;
  183. /* Kick channel to continue */
  184. DBDMA_kick(container_of(ch, DBDMAState, channels[ch->channel]));
  185. }
  186. }
  187. static void screamer_update_settings(ScreamerState *s)
  188. {
  189. struct audsettings as = { s->rate, 2, AUDIO_FORMAT_S16,
  190. 1 };
  191. s->voice = AUD_open_out(&s->card, s->voice, s_spk, s, screamerspk_callback, &as);
  192. if (!s->voice) {
  193. AUD_log(s_spk, "Could not open voice\n");
  194. return;
  195. }
  196. s->shift = 2;
  197. s->samples = AUD_get_buffer_size_out(s->voice) >> s->shift;
  198. s->mixbuf = g_malloc0(s->samples << s->shift);
  199. AUD_set_active_out(s->voice, true);
  200. }
  201. static void screamer_update_volume(ScreamerState *s)
  202. {
  203. uint8_t muted = s->codec_ctrl_regs[0x1] & 0x80 ? 1 : 0;
  204. uint8_t att_left = (s->codec_ctrl_regs[0x4] & 0xf);
  205. uint8_t att_right = (s->codec_ctrl_regs[0x4] & 0x3c0) >> 6;
  206. SCREAMER_DPRINTF("setting mute: %d, attenuation L: %d R: %d\n",
  207. muted, att_left, att_right);
  208. AUD_set_volume_out(s->voice, muted, (0xf - att_left) << 4,
  209. (0xf - att_right) << 4);
  210. }
  211. static void screamer_reset(DeviceState *dev)
  212. {
  213. ScreamerState *s = SCREAMER(dev);
  214. memset(s->regs, 0, sizeof(s->regs));
  215. memset(s->codec_ctrl_regs, 0, sizeof(s->codec_ctrl_regs));
  216. memset(&s->io, 0, sizeof(DBDMA_io));
  217. s->rate = 44100;
  218. screamer_update_settings(s);
  219. s->bpos = 0;
  220. s->ppos = 0;
  221. return;
  222. }
  223. static void screamer_realizefn(DeviceState *dev, Error **errp)
  224. {
  225. ScreamerState *s = SCREAMER(dev);
  226. if (!AUD_register_card(s_spk, &s->card, errp)) {
  227. return;
  228. }
  229. s->rate = 44100;
  230. screamer_update_settings(s);
  231. }
  232. static void screamer_control_write(ScreamerState *s, uint32_t val)
  233. {
  234. SCREAMER_DPRINTF("%s: val %" PRId32 "\n", __func__, val);
  235. /* Basic rate selection */
  236. switch ((val & 0x700) >> 8) {
  237. case 0x00:
  238. s->rate = 44100;
  239. break;
  240. case 0x1:
  241. s->rate = 29400;
  242. break;
  243. case 0x2:
  244. s->rate = 22050;
  245. break;
  246. case 0x3:
  247. s->rate = 17640;
  248. break;
  249. case 0x4:
  250. s->rate = 14700;
  251. break;
  252. case 0x5:
  253. s->rate = 11025;
  254. break;
  255. case 0x6:
  256. s->rate = 8820;
  257. break;
  258. case 0x7:
  259. s->rate = 7350;
  260. break;
  261. }
  262. SCREAMER_DPRINTF("basic rate: %d\n", s->rate);
  263. screamer_update_settings(s);
  264. s->regs[0] = val;
  265. }
  266. static void screamer_codec_write(ScreamerState *s, hwaddr addr, uint64_t val)
  267. {
  268. //SCREAMER_DPRINTF("%s: addr " HWADDR_PRIx " val %" PRIx64 "\n", __func__, addr, val);
  269. switch (addr) {
  270. case 0x1:
  271. /* Clear recalibrate if set */
  272. val = val & ~CODEC_CTRL1_RECALIBRATE;
  273. /* Update volume in case mute set */
  274. screamer_update_volume(s);
  275. break;
  276. case 0x4:
  277. /* Speaker attenuation */
  278. screamer_update_volume(s);
  279. break;
  280. }
  281. s->codec_ctrl_regs[addr] = val;
  282. }
  283. static uint64_t screamer_read(void *opaque, hwaddr addr, unsigned size)
  284. {
  285. ScreamerState *s = opaque;
  286. uint32_t val;
  287. addr = addr >> 4;
  288. switch (addr) {
  289. case SND_CTRL_REG:
  290. val = s->regs[addr];
  291. break;
  292. case CODEC_CTRL_REG:
  293. val = s->regs[addr] & ~CODEC_CTRL_MASKECMD;
  294. break;
  295. case CODEC_STAT_REG:
  296. if (s->codec_ctrl_regs[7] & 1) {
  297. /* Read back mode */
  298. val = s->codec_ctrl_regs[(s->codec_ctrl_regs[7] >> 1) & 0xe];
  299. } else {
  300. /* Return status register */
  301. val = s->regs[addr] & ~0xff00;
  302. val |= CODEC_STAT_MANUFACTURER_CRYSTAL | CODEC_STAT_AWACS_REVISION |
  303. CODEC_STAT_MASK_VALID;
  304. }
  305. break;
  306. case CLIP_CNT_REG:
  307. case BYTE_SWAP_REG:
  308. case FRAME_CNT_REG:
  309. val = s->regs[addr];
  310. break;
  311. default:
  312. qemu_log_mask(LOG_UNIMP,
  313. "screamer: Unimplemented register read "
  314. "reg 0x%" HWADDR_PRIx " size 0x%x\n",
  315. addr, size);
  316. val = 0;
  317. break;
  318. }
  319. SCREAMER_DPRINTF("%s: addr " HWADDR_FMT_plx " -> %x\n", __func__, addr, val);
  320. return val;
  321. }
  322. static void screamer_write(void *opaque, hwaddr addr,
  323. uint64_t val, unsigned size)
  324. {
  325. ScreamerState *s = opaque;
  326. uint32_t codec_addr;
  327. addr = addr >> 4;
  328. SCREAMER_DPRINTF("%s: addr " HWADDR_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
  329. switch (addr) {
  330. case SND_CTRL_REG:
  331. screamer_control_write(s, val & 0xffffffff);
  332. break;
  333. case CODEC_CTRL_REG:
  334. s->regs[addr] = val & 0xffffffff;
  335. codec_addr = (val & 0x7fff) >> 12;
  336. screamer_codec_write(s, codec_addr, val & 0xfff);
  337. break;
  338. case CODEC_STAT_REG:
  339. case CLIP_CNT_REG:
  340. case BYTE_SWAP_REG:
  341. s->regs[addr] = val & 0xffffffff;
  342. break;
  343. default:
  344. qemu_log_mask(LOG_UNIMP,
  345. "screamer: Unimplemented register write "
  346. "reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
  347. addr, size, val);
  348. break;
  349. }
  350. return;
  351. }
  352. static const MemoryRegionOps screamer_ops = {
  353. .read = screamer_read,
  354. .write = screamer_write,
  355. .endianness = DEVICE_LITTLE_ENDIAN,
  356. .valid = {
  357. .min_access_size = 4,
  358. .max_access_size = 4,
  359. }
  360. };
  361. static void screamer_initfn(Object *obj)
  362. {
  363. SysBusDevice *d = SYS_BUS_DEVICE(obj);
  364. ScreamerState *s = SCREAMER(obj);
  365. memory_region_init_io(&s->mem, obj, &screamer_ops, s, "screamer", 0x1000);
  366. sysbus_init_mmio(d, &s->mem);
  367. sysbus_init_irq(d, &s->irq);
  368. sysbus_init_irq(d, &s->dma_tx_irq);
  369. sysbus_init_irq(d, &s->dma_rx_irq);
  370. }
  371. static const Property screamer_properties[] = {
  372. DEFINE_AUDIO_PROPERTIES(ScreamerState, card),
  373. };
  374. static void screamer_class_init(ObjectClass *oc, void *data)
  375. {
  376. DeviceClass *dc = DEVICE_CLASS(oc);
  377. dc->realize = screamer_realizefn;
  378. device_class_set_legacy_reset(dc, screamer_reset);
  379. device_class_set_props(dc, screamer_properties);
  380. }
  381. static const TypeInfo screamer_type_info = {
  382. .name = TYPE_SCREAMER,
  383. .parent = TYPE_SYS_BUS_DEVICE,
  384. .instance_size = sizeof(ScreamerState),
  385. .instance_init = screamer_initfn,
  386. .class_init = screamer_class_init,
  387. };
  388. static void screamer_register_types(void)
  389. {
  390. type_register_static(&screamer_type_info);
  391. }
  392. type_init(screamer_register_types)