linux/sound/soc/intel/baytrail/sst-baytrail-ipc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Intel Baytrail SST IPC Support
   4 * Copyright (c) 2014, Intel Corporation.
   5 */
   6
   7#include <linux/types.h>
   8#include <linux/kernel.h>
   9#include <linux/list.h>
  10#include <linux/device.h>
  11#include <linux/wait.h>
  12#include <linux/spinlock.h>
  13#include <linux/workqueue.h>
  14#include <linux/export.h>
  15#include <linux/slab.h>
  16#include <linux/delay.h>
  17#include <linux/platform_device.h>
  18#include <linux/firmware.h>
  19#include <linux/io.h>
  20#include <asm/div64.h>
  21
  22#include "sst-baytrail-ipc.h"
  23#include "../common/sst-dsp.h"
  24#include "../common/sst-dsp-priv.h"
  25#include "../common/sst-ipc.h"
  26
  27/* IPC message timeout */
  28#define IPC_TIMEOUT_MSECS       300
  29#define IPC_BOOT_MSECS          200
  30
  31#define IPC_EMPTY_LIST_SIZE     8
  32
  33/* IPC header bits */
  34#define IPC_HEADER_MSG_ID_MASK  0xff
  35#define IPC_HEADER_MSG_ID(x)    ((x) & IPC_HEADER_MSG_ID_MASK)
  36#define IPC_HEADER_STR_ID_SHIFT 8
  37#define IPC_HEADER_STR_ID_MASK  0x1f
  38#define IPC_HEADER_STR_ID(x)    (((x) & 0x1f) << IPC_HEADER_STR_ID_SHIFT)
  39#define IPC_HEADER_LARGE_SHIFT  13
  40#define IPC_HEADER_LARGE(x)     (((x) & 0x1) << IPC_HEADER_LARGE_SHIFT)
  41#define IPC_HEADER_DATA_SHIFT   16
  42#define IPC_HEADER_DATA_MASK    0x3fff
  43#define IPC_HEADER_DATA(x)      (((x) & 0x3fff) << IPC_HEADER_DATA_SHIFT)
  44
  45/* mask for differentiating between notification and reply message */
  46#define IPC_NOTIFICATION        (0x1 << 7)
  47
  48/* I2L Stream config/control msgs */
  49#define IPC_IA_ALLOC_STREAM     0x20
  50#define IPC_IA_FREE_STREAM      0x21
  51#define IPC_IA_PAUSE_STREAM     0x24
  52#define IPC_IA_RESUME_STREAM    0x25
  53#define IPC_IA_DROP_STREAM      0x26
  54#define IPC_IA_START_STREAM     0x30
  55
  56/* notification messages */
  57#define IPC_IA_FW_INIT_CMPLT    0x81
  58#define IPC_SST_PERIOD_ELAPSED  0x97
  59
  60/* IPC messages between host and ADSP */
  61struct sst_byt_address_info {
  62        u32 addr;
  63        u32 size;
  64} __packed;
  65
  66struct sst_byt_str_type {
  67        u8 codec_type;
  68        u8 str_type;
  69        u8 operation;
  70        u8 protected_str;
  71        u8 time_slots;
  72        u8 reserved;
  73        u16 result;
  74} __packed;
  75
  76struct sst_byt_pcm_params {
  77        u8 num_chan;
  78        u8 pcm_wd_sz;
  79        u8 use_offload_path;
  80        u8 reserved;
  81        u32 sfreq;
  82        u8 channel_map[8];
  83} __packed;
  84
  85struct sst_byt_frames_info {
  86        u16 num_entries;
  87        u16 rsrvd;
  88        u32 frag_size;
  89        struct sst_byt_address_info ring_buf_info[8];
  90} __packed;
  91
  92struct sst_byt_alloc_params {
  93        struct sst_byt_str_type str_type;
  94        struct sst_byt_pcm_params pcm_params;
  95        struct sst_byt_frames_info frame_info;
  96} __packed;
  97
  98struct sst_byt_alloc_response {
  99        struct sst_byt_str_type str_type;
 100        u8 reserved[88];
 101} __packed;
 102
 103struct sst_byt_start_stream_params {
 104        u32 byte_offset;
 105} __packed;
 106
 107struct sst_byt_tstamp {
 108        u64 ring_buffer_counter;
 109        u64 hardware_counter;
 110        u64 frames_decoded;
 111        u64 bytes_decoded;
 112        u64 bytes_copied;
 113        u32 sampling_frequency;
 114        u32 channel_peak[8];
 115} __packed;
 116
 117struct sst_byt_fw_version {
 118        u8 build;
 119        u8 minor;
 120        u8 major;
 121        u8 type;
 122} __packed;
 123
 124struct sst_byt_fw_build_info {
 125        u8 date[16];
 126        u8 time[16];
 127} __packed;
 128
 129struct sst_byt_fw_init {
 130        struct sst_byt_fw_version fw_version;
 131        struct sst_byt_fw_build_info build_info;
 132        u16 result;
 133        u8 module_id;
 134        u8 debug_info;
 135} __packed;
 136
 137struct sst_byt_stream;
 138struct sst_byt;
 139
 140/* stream infomation */
 141struct sst_byt_stream {
 142        struct list_head node;
 143
 144        /* configuration */
 145        struct sst_byt_alloc_params request;
 146        struct sst_byt_alloc_response reply;
 147
 148        /* runtime info */
 149        struct sst_byt *byt;
 150        int str_id;
 151        bool commited;
 152        bool running;
 153
 154        /* driver callback */
 155        u32 (*notify_position)(struct sst_byt_stream *stream, void *data);
 156        void *pdata;
 157};
 158
 159/* SST Baytrail IPC data */
 160struct sst_byt {
 161        struct device *dev;
 162        struct sst_dsp *dsp;
 163
 164        /* stream */
 165        struct list_head stream_list;
 166
 167        /* boot */
 168        wait_queue_head_t boot_wait;
 169        bool boot_complete;
 170        struct sst_fw *fw;
 171
 172        /* IPC messaging */
 173        struct sst_generic_ipc ipc;
 174};
 175
 176static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id)
 177{
 178        return IPC_HEADER_MSG_ID(msg_id) | IPC_HEADER_STR_ID(str_id) |
 179               IPC_HEADER_LARGE(large) | IPC_HEADER_DATA(data) |
 180               SST_BYT_IPCX_BUSY;
 181}
 182
 183static inline u16 sst_byt_header_msg_id(u64 header)
 184{
 185        return header & IPC_HEADER_MSG_ID_MASK;
 186}
 187
 188static inline u8 sst_byt_header_str_id(u64 header)
 189{
 190        return (header >> IPC_HEADER_STR_ID_SHIFT) & IPC_HEADER_STR_ID_MASK;
 191}
 192
 193static inline u16 sst_byt_header_data(u64 header)
 194{
 195        return (header >> IPC_HEADER_DATA_SHIFT) & IPC_HEADER_DATA_MASK;
 196}
 197
 198static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt,
 199                                                 int stream_id)
 200{
 201        struct sst_byt_stream *stream;
 202
 203        list_for_each_entry(stream, &byt->stream_list, node) {
 204                if (stream->str_id == stream_id)
 205                        return stream;
 206        }
 207
 208        return NULL;
 209}
 210
 211static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg)
 212{
 213        struct sst_byt_stream *stream;
 214        u64 header = msg->tx.header;
 215        u8 stream_id = sst_byt_header_str_id(header);
 216        u8 stream_msg = sst_byt_header_msg_id(header);
 217
 218        stream = sst_byt_get_stream(byt, stream_id);
 219        if (stream == NULL)
 220                return;
 221
 222        switch (stream_msg) {
 223        case IPC_IA_DROP_STREAM:
 224        case IPC_IA_PAUSE_STREAM:
 225        case IPC_IA_FREE_STREAM:
 226                stream->running = false;
 227                break;
 228        case IPC_IA_START_STREAM:
 229        case IPC_IA_RESUME_STREAM:
 230                stream->running = true;
 231                break;
 232        }
 233}
 234
 235static int sst_byt_process_reply(struct sst_byt *byt, u64 header)
 236{
 237        struct ipc_message *msg;
 238
 239        msg = sst_ipc_reply_find_msg(&byt->ipc, header);
 240        if (msg == NULL)
 241                return 1;
 242
 243        msg->rx.header = header;
 244        if (header & IPC_HEADER_LARGE(true)) {
 245                msg->rx.size = sst_byt_header_data(header);
 246                sst_dsp_inbox_read(byt->dsp, msg->rx.data, msg->rx.size);
 247        }
 248
 249        /* update any stream states */
 250        sst_byt_stream_update(byt, msg);
 251
 252        list_del(&msg->list);
 253        /* wake up */
 254        sst_ipc_tx_msg_reply_complete(&byt->ipc, msg);
 255
 256        return 1;
 257}
 258
 259static void sst_byt_fw_ready(struct sst_byt *byt, u64 header)
 260{
 261        dev_dbg(byt->dev, "ipc: DSP is ready 0x%llX\n", header);
 262
 263        byt->boot_complete = true;
 264        wake_up(&byt->boot_wait);
 265}
 266
 267static int sst_byt_process_notification(struct sst_byt *byt,
 268                                        unsigned long *flags)
 269{
 270        struct sst_dsp *sst = byt->dsp;
 271        struct sst_byt_stream *stream;
 272        u64 header;
 273        u8 msg_id, stream_id;
 274
 275        header = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
 276        msg_id = sst_byt_header_msg_id(header);
 277
 278        switch (msg_id) {
 279        case IPC_SST_PERIOD_ELAPSED:
 280                stream_id = sst_byt_header_str_id(header);
 281                stream = sst_byt_get_stream(byt, stream_id);
 282                if (stream && stream->running && stream->notify_position) {
 283                        spin_unlock_irqrestore(&sst->spinlock, *flags);
 284                        stream->notify_position(stream, stream->pdata);
 285                        spin_lock_irqsave(&sst->spinlock, *flags);
 286                }
 287                break;
 288        case IPC_IA_FW_INIT_CMPLT:
 289                sst_byt_fw_ready(byt, header);
 290                break;
 291        }
 292
 293        return 1;
 294}
 295
 296static irqreturn_t sst_byt_irq_thread(int irq, void *context)
 297{
 298        struct sst_dsp *sst = (struct sst_dsp *) context;
 299        struct sst_byt *byt = sst_dsp_get_thread_context(sst);
 300        struct sst_generic_ipc *ipc = &byt->ipc;
 301        u64 header;
 302        unsigned long flags;
 303
 304        spin_lock_irqsave(&sst->spinlock, flags);
 305
 306        header = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
 307        if (header & SST_BYT_IPCD_BUSY) {
 308                if (header & IPC_NOTIFICATION) {
 309                        /* message from ADSP */
 310                        sst_byt_process_notification(byt, &flags);
 311                } else {
 312                        /* reply from ADSP */
 313                        sst_byt_process_reply(byt, header);
 314                }
 315                /*
 316                 * clear IPCD BUSY bit and set DONE bit. Tell DSP we have
 317                 * processed the message and can accept new. Clear data part
 318                 * of the header
 319                 */
 320                sst_dsp_shim_update_bits64_unlocked(sst, SST_IPCD,
 321                        SST_BYT_IPCD_DONE | SST_BYT_IPCD_BUSY |
 322                        IPC_HEADER_DATA(IPC_HEADER_DATA_MASK),
 323                        SST_BYT_IPCD_DONE);
 324                /* unmask message request interrupts */
 325                sst_dsp_shim_update_bits64_unlocked(sst, SST_IMRX,
 326                        SST_BYT_IMRX_REQUEST, 0);
 327        }
 328
 329        spin_unlock_irqrestore(&sst->spinlock, flags);
 330
 331        /* continue to send any remaining messages... */
 332        schedule_work(&ipc->kwork);
 333
 334        return IRQ_HANDLED;
 335}
 336
 337/* stream API */
 338struct sst_byt_stream *sst_byt_stream_new(struct sst_byt *byt, int id,
 339        u32 (*notify_position)(struct sst_byt_stream *stream, void *data),
 340        void *data)
 341{
 342        struct sst_byt_stream *stream;
 343        struct sst_dsp *sst = byt->dsp;
 344        unsigned long flags;
 345
 346        stream = kzalloc(sizeof(*stream), GFP_KERNEL);
 347        if (stream == NULL)
 348                return NULL;
 349
 350        spin_lock_irqsave(&sst->spinlock, flags);
 351        list_add(&stream->node, &byt->stream_list);
 352        stream->notify_position = notify_position;
 353        stream->pdata = data;
 354        stream->byt = byt;
 355        stream->str_id = id;
 356        spin_unlock_irqrestore(&sst->spinlock, flags);
 357
 358        return stream;
 359}
 360
 361int sst_byt_stream_set_bits(struct sst_byt *byt, struct sst_byt_stream *stream,
 362                            int bits)
 363{
 364        stream->request.pcm_params.pcm_wd_sz = bits;
 365        return 0;
 366}
 367
 368int sst_byt_stream_set_channels(struct sst_byt *byt,
 369                                struct sst_byt_stream *stream, u8 channels)
 370{
 371        stream->request.pcm_params.num_chan = channels;
 372        return 0;
 373}
 374
 375int sst_byt_stream_set_rate(struct sst_byt *byt, struct sst_byt_stream *stream,
 376                            unsigned int rate)
 377{
 378        stream->request.pcm_params.sfreq = rate;
 379        return 0;
 380}
 381
 382/* stream sonfiguration */
 383int sst_byt_stream_type(struct sst_byt *byt, struct sst_byt_stream *stream,
 384                        int codec_type, int stream_type, int operation)
 385{
 386        stream->request.str_type.codec_type = codec_type;
 387        stream->request.str_type.str_type = stream_type;
 388        stream->request.str_type.operation = operation;
 389        stream->request.str_type.time_slots = 0xc;
 390
 391        return 0;
 392}
 393
 394int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream,
 395                          uint32_t buffer_addr, uint32_t buffer_size)
 396{
 397        stream->request.frame_info.num_entries = 1;
 398        stream->request.frame_info.ring_buf_info[0].addr = buffer_addr;
 399        stream->request.frame_info.ring_buf_info[0].size = buffer_size;
 400        /* calculate bytes per 4 ms fragment */
 401        stream->request.frame_info.frag_size =
 402                stream->request.pcm_params.sfreq *
 403                stream->request.pcm_params.num_chan *
 404                stream->request.pcm_params.pcm_wd_sz / 8 *
 405                4 / 1000;
 406        return 0;
 407}
 408
 409int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
 410{
 411        struct sst_ipc_message request, reply = {0};
 412        int ret;
 413
 414        request.header = sst_byt_header(IPC_IA_ALLOC_STREAM,
 415                                sizeof(stream->request) + sizeof(u32),
 416                                true, stream->str_id);
 417        request.data = &stream->request;
 418        request.size = sizeof(stream->request);
 419        reply.data = &stream->reply;
 420        reply.size = sizeof(stream->reply);
 421
 422        ret = sst_ipc_tx_message_wait(&byt->ipc, request, &reply);
 423        if (ret < 0) {
 424                dev_err(byt->dev, "ipc: error stream commit failed\n");
 425                return ret;
 426        }
 427
 428        stream->commited = true;
 429
 430        return 0;
 431}
 432
 433int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
 434{
 435        struct sst_ipc_message request = {0};
 436        int ret = 0;
 437        struct sst_dsp *sst = byt->dsp;
 438        unsigned long flags;
 439
 440        if (!stream->commited)
 441                goto out;
 442
 443        request.header = sst_byt_header(IPC_IA_FREE_STREAM,
 444                        0, false, stream->str_id);
 445        ret = sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
 446        if (ret < 0) {
 447                dev_err(byt->dev, "ipc: free stream %d failed\n",
 448                        stream->str_id);
 449                return -EAGAIN;
 450        }
 451
 452        stream->commited = false;
 453out:
 454        spin_lock_irqsave(&sst->spinlock, flags);
 455        list_del(&stream->node);
 456        kfree(stream);
 457        spin_unlock_irqrestore(&sst->spinlock, flags);
 458
 459        return ret;
 460}
 461
 462static int sst_byt_stream_operations(struct sst_byt *byt, int type,
 463                                     int stream_id, int wait)
 464{
 465        struct sst_ipc_message request = {0};
 466
 467        request.header = sst_byt_header(type, 0, false, stream_id);
 468        if (wait)
 469                return sst_ipc_tx_message_wait(&byt->ipc, request, NULL);
 470        else
 471                return sst_ipc_tx_message_nowait(&byt->ipc, request);
 472}
 473
 474/* stream ALSA trigger operations */
 475int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream,
 476                         u32 start_offset)
 477{
 478        struct sst_byt_start_stream_params start_stream;
 479        struct sst_ipc_message request;
 480        int ret;
 481
 482        start_stream.byte_offset = start_offset;
 483        request.header = sst_byt_header(IPC_IA_START_STREAM,
 484                                sizeof(start_stream) + sizeof(u32),
 485                                true, stream->str_id);
 486        request.data = &start_stream;
 487        request.size = sizeof(start_stream);
 488
 489        ret = sst_ipc_tx_message_nowait(&byt->ipc, request);
 490        if (ret < 0)
 491                dev_err(byt->dev, "ipc: error failed to start stream %d\n",
 492                        stream->str_id);
 493
 494        return ret;
 495}
 496
 497int sst_byt_stream_stop(struct sst_byt *byt, struct sst_byt_stream *stream)
 498{
 499        int ret;
 500
 501        /* don't stop streams that are not commited */
 502        if (!stream->commited)
 503                return 0;
 504
 505        ret = sst_byt_stream_operations(byt, IPC_IA_DROP_STREAM,
 506                                        stream->str_id, 0);
 507        if (ret < 0)
 508                dev_err(byt->dev, "ipc: error failed to stop stream %d\n",
 509                        stream->str_id);
 510        return ret;
 511}
 512
 513int sst_byt_stream_pause(struct sst_byt *byt, struct sst_byt_stream *stream)
 514{
 515        int ret;
 516
 517        ret = sst_byt_stream_operations(byt, IPC_IA_PAUSE_STREAM,
 518                                        stream->str_id, 0);
 519        if (ret < 0)
 520                dev_err(byt->dev, "ipc: error failed to pause stream %d\n",
 521                        stream->str_id);
 522
 523        return ret;
 524}
 525
 526int sst_byt_stream_resume(struct sst_byt *byt, struct sst_byt_stream *stream)
 527{
 528        int ret;
 529
 530        ret = sst_byt_stream_operations(byt, IPC_IA_RESUME_STREAM,
 531                                        stream->str_id, 0);
 532        if (ret < 0)
 533                dev_err(byt->dev, "ipc: error failed to resume stream %d\n",
 534                        stream->str_id);
 535
 536        return ret;
 537}
 538
 539int sst_byt_get_dsp_position(struct sst_byt *byt,
 540                             struct sst_byt_stream *stream, int buffer_size)
 541{
 542        struct sst_dsp *sst = byt->dsp;
 543        struct sst_byt_tstamp fw_tstamp;
 544        u8 str_id = stream->str_id;
 545        u32 tstamp_offset;
 546
 547        tstamp_offset = SST_BYT_TIMESTAMP_OFFSET + str_id * sizeof(fw_tstamp);
 548        memcpy_fromio(&fw_tstamp,
 549                      sst->addr.lpe + tstamp_offset, sizeof(fw_tstamp));
 550
 551        return do_div(fw_tstamp.ring_buffer_counter, buffer_size);
 552}
 553
 554struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt)
 555{
 556        return byt->dsp;
 557}
 558
 559static struct sst_dsp_device byt_dev = {
 560        .thread = sst_byt_irq_thread,
 561        .ops = &sst_byt_ops,
 562};
 563
 564int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata)
 565{
 566        struct sst_byt *byt = pdata->dsp;
 567
 568        dev_dbg(byt->dev, "dsp reset\n");
 569        sst_dsp_reset(byt->dsp);
 570        sst_ipc_drop_all(&byt->ipc);
 571        dev_dbg(byt->dev, "dsp in reset\n");
 572
 573        dev_dbg(byt->dev, "free all blocks and unload fw\n");
 574        sst_fw_unload(byt->fw);
 575
 576        return 0;
 577}
 578EXPORT_SYMBOL_GPL(sst_byt_dsp_suspend_late);
 579
 580int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata)
 581{
 582        struct sst_byt *byt = pdata->dsp;
 583        int ret;
 584
 585        dev_dbg(byt->dev, "reload dsp fw\n");
 586
 587        sst_dsp_reset(byt->dsp);
 588
 589        ret = sst_fw_reload(byt->fw);
 590        if (ret <  0) {
 591                dev_err(dev, "error: failed to reload firmware\n");
 592                return ret;
 593        }
 594
 595        /* wait for DSP boot completion */
 596        byt->boot_complete = false;
 597        sst_dsp_boot(byt->dsp);
 598        dev_dbg(byt->dev, "dsp booting...\n");
 599
 600        return 0;
 601}
 602EXPORT_SYMBOL_GPL(sst_byt_dsp_boot);
 603
 604int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata)
 605{
 606        struct sst_byt *byt = pdata->dsp;
 607        int err;
 608
 609        dev_dbg(byt->dev, "wait for dsp reboot\n");
 610
 611        err = wait_event_timeout(byt->boot_wait, byt->boot_complete,
 612                                 msecs_to_jiffies(IPC_BOOT_MSECS));
 613        if (err == 0) {
 614                dev_err(byt->dev, "ipc: error DSP boot timeout\n");
 615                return -EIO;
 616        }
 617
 618        dev_dbg(byt->dev, "dsp rebooted\n");
 619        return 0;
 620}
 621EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready);
 622
 623static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
 624{
 625        if (msg->tx.header & IPC_HEADER_LARGE(true))
 626                sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size);
 627
 628        sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->tx.header);
 629}
 630
 631static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
 632{
 633        struct sst_dsp *sst = ipc->dsp;
 634        u64 isr, ipcd, imrx, ipcx;
 635
 636        ipcx = sst_dsp_shim_read64_unlocked(sst, SST_IPCX);
 637        isr = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
 638        ipcd = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
 639        imrx = sst_dsp_shim_read64_unlocked(sst, SST_IMRX);
 640
 641        dev_err(ipc->dev,
 642                "ipc: --%s-- ipcx 0x%llx isr 0x%llx ipcd 0x%llx imrx 0x%llx\n",
 643                text, ipcx, isr, ipcd, imrx);
 644}
 645
 646static void byt_tx_data_copy(struct ipc_message *msg, char *tx_data,
 647        size_t tx_size)
 648{
 649        /* msg content = lower 32-bit of the header + data */
 650        *(u32 *)msg->tx.data = (u32)(msg->tx.header & (u32)-1);
 651        memcpy(msg->tx.data + sizeof(u32), tx_data, tx_size);
 652        msg->tx.size += sizeof(u32);
 653}
 654
 655static u64 byt_reply_msg_match(u64 header, u64 *mask)
 656{
 657        /* match reply to message sent based on msg and stream IDs */
 658        *mask = IPC_HEADER_MSG_ID_MASK |
 659               IPC_HEADER_STR_ID_MASK << IPC_HEADER_STR_ID_SHIFT;
 660        header &= *mask;
 661
 662        return header;
 663}
 664
 665static bool byt_is_dsp_busy(struct sst_dsp *dsp)
 666{
 667        u64 ipcx;
 668
 669        ipcx = sst_dsp_shim_read_unlocked(dsp, SST_IPCX);
 670        return (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE));
 671}
 672
 673int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)
 674{
 675        struct sst_byt *byt;
 676        struct sst_generic_ipc *ipc;
 677        struct sst_fw *byt_sst_fw;
 678        struct sst_byt_fw_init init;
 679        int err;
 680
 681        dev_dbg(dev, "initialising Byt DSP IPC\n");
 682
 683        byt = devm_kzalloc(dev, sizeof(*byt), GFP_KERNEL);
 684        if (byt == NULL)
 685                return -ENOMEM;
 686
 687        byt->dev = dev;
 688
 689        ipc = &byt->ipc;
 690        ipc->dev = dev;
 691        ipc->ops.tx_msg = byt_tx_msg;
 692        ipc->ops.shim_dbg = byt_shim_dbg;
 693        ipc->ops.tx_data_copy = byt_tx_data_copy;
 694        ipc->ops.reply_msg_match = byt_reply_msg_match;
 695        ipc->ops.is_dsp_busy = byt_is_dsp_busy;
 696        ipc->tx_data_max_size = IPC_MAX_MAILBOX_BYTES;
 697        ipc->rx_data_max_size = IPC_MAX_MAILBOX_BYTES;
 698
 699        err = sst_ipc_init(ipc);
 700        if (err != 0)
 701                goto ipc_init_err;
 702
 703        INIT_LIST_HEAD(&byt->stream_list);
 704        init_waitqueue_head(&byt->boot_wait);
 705        byt_dev.thread_context = byt;
 706
 707        /* init SST shim */
 708        byt->dsp = sst_dsp_new(dev, &byt_dev, pdata);
 709        if (byt->dsp == NULL) {
 710                err = -ENODEV;
 711                goto dsp_new_err;
 712        }
 713
 714        ipc->dsp = byt->dsp;
 715
 716        /* keep the DSP in reset state for base FW loading */
 717        sst_dsp_reset(byt->dsp);
 718
 719        byt_sst_fw = sst_fw_new(byt->dsp, pdata->fw, byt);
 720        if (byt_sst_fw  == NULL) {
 721                err = -ENODEV;
 722                dev_err(dev, "error: failed to load firmware\n");
 723                goto fw_err;
 724        }
 725
 726        /* wait for DSP boot completion */
 727        sst_dsp_boot(byt->dsp);
 728        err = wait_event_timeout(byt->boot_wait, byt->boot_complete,
 729                                 msecs_to_jiffies(IPC_BOOT_MSECS));
 730        if (err == 0) {
 731                err = -EIO;
 732                dev_err(byt->dev, "ipc: error DSP boot timeout\n");
 733                goto boot_err;
 734        }
 735
 736        /* show firmware information */
 737        sst_dsp_inbox_read(byt->dsp, &init, sizeof(init));
 738        dev_info(byt->dev, "FW version: %02x.%02x.%02x.%02x\n",
 739                 init.fw_version.major, init.fw_version.minor,
 740                 init.fw_version.build, init.fw_version.type);
 741        dev_info(byt->dev, "Build type: %x\n", init.fw_version.type);
 742        dev_info(byt->dev, "Build date: %s %s\n",
 743                 init.build_info.date, init.build_info.time);
 744
 745        pdata->dsp = byt;
 746        byt->fw = byt_sst_fw;
 747
 748        return 0;
 749
 750boot_err:
 751        sst_dsp_reset(byt->dsp);
 752        sst_fw_free(byt_sst_fw);
 753fw_err:
 754        sst_dsp_free(byt->dsp);
 755dsp_new_err:
 756        sst_ipc_fini(ipc);
 757ipc_init_err:
 758
 759        return err;
 760}
 761EXPORT_SYMBOL_GPL(sst_byt_dsp_init);
 762
 763void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata)
 764{
 765        struct sst_byt *byt = pdata->dsp;
 766
 767        sst_dsp_reset(byt->dsp);
 768        sst_fw_free_all(byt->dsp);
 769        sst_dsp_free(byt->dsp);
 770        sst_ipc_fini(&byt->ipc);
 771}
 772EXPORT_SYMBOL_GPL(sst_byt_dsp_free);
 773