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->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        if (header & IPC_HEADER_LARGE(true)) {
 244                msg->rx_size = sst_byt_header_data(header);
 245                sst_dsp_inbox_read(byt->dsp, msg->rx_data, msg->rx_size);
 246        }
 247
 248        /* update any stream states */
 249        sst_byt_stream_update(byt, msg);
 250
 251        list_del(&msg->list);
 252        /* wake up */
 253        sst_ipc_tx_msg_reply_complete(&byt->ipc, msg);
 254
 255        return 1;
 256}
 257
 258static void sst_byt_fw_ready(struct sst_byt *byt, u64 header)
 259{
 260        dev_dbg(byt->dev, "ipc: DSP is ready 0x%llX\n", header);
 261
 262        byt->boot_complete = true;
 263        wake_up(&byt->boot_wait);
 264}
 265
 266static int sst_byt_process_notification(struct sst_byt *byt,
 267                                        unsigned long *flags)
 268{
 269        struct sst_dsp *sst = byt->dsp;
 270        struct sst_byt_stream *stream;
 271        u64 header;
 272        u8 msg_id, stream_id;
 273
 274        header = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
 275        msg_id = sst_byt_header_msg_id(header);
 276
 277        switch (msg_id) {
 278        case IPC_SST_PERIOD_ELAPSED:
 279                stream_id = sst_byt_header_str_id(header);
 280                stream = sst_byt_get_stream(byt, stream_id);
 281                if (stream && stream->running && stream->notify_position) {
 282                        spin_unlock_irqrestore(&sst->spinlock, *flags);
 283                        stream->notify_position(stream, stream->pdata);
 284                        spin_lock_irqsave(&sst->spinlock, *flags);
 285                }
 286                break;
 287        case IPC_IA_FW_INIT_CMPLT:
 288                sst_byt_fw_ready(byt, header);
 289                break;
 290        }
 291
 292        return 1;
 293}
 294
 295static irqreturn_t sst_byt_irq_thread(int irq, void *context)
 296{
 297        struct sst_dsp *sst = (struct sst_dsp *) context;
 298        struct sst_byt *byt = sst_dsp_get_thread_context(sst);
 299        struct sst_generic_ipc *ipc = &byt->ipc;
 300        u64 header;
 301        unsigned long flags;
 302
 303        spin_lock_irqsave(&sst->spinlock, flags);
 304
 305        header = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
 306        if (header & SST_BYT_IPCD_BUSY) {
 307                if (header & IPC_NOTIFICATION) {
 308                        /* message from ADSP */
 309                        sst_byt_process_notification(byt, &flags);
 310                } else {
 311                        /* reply from ADSP */
 312                        sst_byt_process_reply(byt, header);
 313                }
 314                /*
 315                 * clear IPCD BUSY bit and set DONE bit. Tell DSP we have
 316                 * processed the message and can accept new. Clear data part
 317                 * of the header
 318                 */
 319                sst_dsp_shim_update_bits64_unlocked(sst, SST_IPCD,
 320                        SST_BYT_IPCD_DONE | SST_BYT_IPCD_BUSY |
 321                        IPC_HEADER_DATA(IPC_HEADER_DATA_MASK),
 322                        SST_BYT_IPCD_DONE);
 323                /* unmask message request interrupts */
 324                sst_dsp_shim_update_bits64_unlocked(sst, SST_IMRX,
 325                        SST_BYT_IMRX_REQUEST, 0);
 326        }
 327
 328        spin_unlock_irqrestore(&sst->spinlock, flags);
 329
 330        /* continue to send any remaining messages... */
 331        schedule_work(&ipc->kwork);
 332
 333        return IRQ_HANDLED;
 334}
 335
 336/* stream API */
 337struct sst_byt_stream *sst_byt_stream_new(struct sst_byt *byt, int id,
 338        u32 (*notify_position)(struct sst_byt_stream *stream, void *data),
 339        void *data)
 340{
 341        struct sst_byt_stream *stream;
 342        struct sst_dsp *sst = byt->dsp;
 343        unsigned long flags;
 344
 345        stream = kzalloc(sizeof(*stream), GFP_KERNEL);
 346        if (stream == NULL)
 347                return NULL;
 348
 349        spin_lock_irqsave(&sst->spinlock, flags);
 350        list_add(&stream->node, &byt->stream_list);
 351        stream->notify_position = notify_position;
 352        stream->pdata = data;
 353        stream->byt = byt;
 354        stream->str_id = id;
 355        spin_unlock_irqrestore(&sst->spinlock, flags);
 356
 357        return stream;
 358}
 359
 360int sst_byt_stream_set_bits(struct sst_byt *byt, struct sst_byt_stream *stream,
 361                            int bits)
 362{
 363        stream->request.pcm_params.pcm_wd_sz = bits;
 364        return 0;
 365}
 366
 367int sst_byt_stream_set_channels(struct sst_byt *byt,
 368                                struct sst_byt_stream *stream, u8 channels)
 369{
 370        stream->request.pcm_params.num_chan = channels;
 371        return 0;
 372}
 373
 374int sst_byt_stream_set_rate(struct sst_byt *byt, struct sst_byt_stream *stream,
 375                            unsigned int rate)
 376{
 377        stream->request.pcm_params.sfreq = rate;
 378        return 0;
 379}
 380
 381/* stream sonfiguration */
 382int sst_byt_stream_type(struct sst_byt *byt, struct sst_byt_stream *stream,
 383                        int codec_type, int stream_type, int operation)
 384{
 385        stream->request.str_type.codec_type = codec_type;
 386        stream->request.str_type.str_type = stream_type;
 387        stream->request.str_type.operation = operation;
 388        stream->request.str_type.time_slots = 0xc;
 389
 390        return 0;
 391}
 392
 393int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream,
 394                          uint32_t buffer_addr, uint32_t buffer_size)
 395{
 396        stream->request.frame_info.num_entries = 1;
 397        stream->request.frame_info.ring_buf_info[0].addr = buffer_addr;
 398        stream->request.frame_info.ring_buf_info[0].size = buffer_size;
 399        /* calculate bytes per 4 ms fragment */
 400        stream->request.frame_info.frag_size =
 401                stream->request.pcm_params.sfreq *
 402                stream->request.pcm_params.num_chan *
 403                stream->request.pcm_params.pcm_wd_sz / 8 *
 404                4 / 1000;
 405        return 0;
 406}
 407
 408int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
 409{
 410        struct sst_byt_alloc_params *str_req = &stream->request;
 411        struct sst_byt_alloc_response *reply = &stream->reply;
 412        u64 header;
 413        int ret;
 414
 415        header = sst_byt_header(IPC_IA_ALLOC_STREAM,
 416                                sizeof(*str_req) + sizeof(u32),
 417                                true, stream->str_id);
 418        ret = sst_ipc_tx_message_wait(&byt->ipc, header, str_req,
 419                                      sizeof(*str_req),
 420                                      reply, sizeof(*reply));
 421        if (ret < 0) {
 422                dev_err(byt->dev, "ipc: error stream commit failed\n");
 423                return ret;
 424        }
 425
 426        stream->commited = true;
 427
 428        return 0;
 429}
 430
 431int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
 432{
 433        u64 header;
 434        int ret = 0;
 435        struct sst_dsp *sst = byt->dsp;
 436        unsigned long flags;
 437
 438        if (!stream->commited)
 439                goto out;
 440
 441        header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id);
 442        ret = sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 0, NULL, 0);
 443        if (ret < 0) {
 444                dev_err(byt->dev, "ipc: free stream %d failed\n",
 445                        stream->str_id);
 446                return -EAGAIN;
 447        }
 448
 449        stream->commited = false;
 450out:
 451        spin_lock_irqsave(&sst->spinlock, flags);
 452        list_del(&stream->node);
 453        kfree(stream);
 454        spin_unlock_irqrestore(&sst->spinlock, flags);
 455
 456        return ret;
 457}
 458
 459static int sst_byt_stream_operations(struct sst_byt *byt, int type,
 460                                     int stream_id, int wait)
 461{
 462        u64 header;
 463
 464        header = sst_byt_header(type, 0, false, stream_id);
 465        if (wait)
 466                return sst_ipc_tx_message_wait(&byt->ipc, header, NULL,
 467                                                0, NULL, 0);
 468        else
 469                return sst_ipc_tx_message_nowait(&byt->ipc, header,
 470                                                NULL, 0);
 471}
 472
 473/* stream ALSA trigger operations */
 474int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream,
 475                         u32 start_offset)
 476{
 477        struct sst_byt_start_stream_params start_stream;
 478        void *tx_msg;
 479        size_t size;
 480        u64 header;
 481        int ret;
 482
 483        start_stream.byte_offset = start_offset;
 484        header = sst_byt_header(IPC_IA_START_STREAM,
 485                                sizeof(start_stream) + sizeof(u32),
 486                                true, stream->str_id);
 487        tx_msg = &start_stream;
 488        size = sizeof(start_stream);
 489
 490        ret = sst_ipc_tx_message_nowait(&byt->ipc, header, tx_msg, size);
 491        if (ret < 0)
 492                dev_err(byt->dev, "ipc: error failed to start stream %d\n",
 493                        stream->str_id);
 494
 495        return ret;
 496}
 497
 498int sst_byt_stream_stop(struct sst_byt *byt, struct sst_byt_stream *stream)
 499{
 500        int ret;
 501
 502        /* don't stop streams that are not commited */
 503        if (!stream->commited)
 504                return 0;
 505
 506        ret = sst_byt_stream_operations(byt, IPC_IA_DROP_STREAM,
 507                                        stream->str_id, 0);
 508        if (ret < 0)
 509                dev_err(byt->dev, "ipc: error failed to stop stream %d\n",
 510                        stream->str_id);
 511        return ret;
 512}
 513
 514int sst_byt_stream_pause(struct sst_byt *byt, struct sst_byt_stream *stream)
 515{
 516        int ret;
 517
 518        ret = sst_byt_stream_operations(byt, IPC_IA_PAUSE_STREAM,
 519                                        stream->str_id, 0);
 520        if (ret < 0)
 521                dev_err(byt->dev, "ipc: error failed to pause stream %d\n",
 522                        stream->str_id);
 523
 524        return ret;
 525}
 526
 527int sst_byt_stream_resume(struct sst_byt *byt, struct sst_byt_stream *stream)
 528{
 529        int ret;
 530
 531        ret = sst_byt_stream_operations(byt, IPC_IA_RESUME_STREAM,
 532                                        stream->str_id, 0);
 533        if (ret < 0)
 534                dev_err(byt->dev, "ipc: error failed to resume stream %d\n",
 535                        stream->str_id);
 536
 537        return ret;
 538}
 539
 540int sst_byt_get_dsp_position(struct sst_byt *byt,
 541                             struct sst_byt_stream *stream, int buffer_size)
 542{
 543        struct sst_dsp *sst = byt->dsp;
 544        struct sst_byt_tstamp fw_tstamp;
 545        u8 str_id = stream->str_id;
 546        u32 tstamp_offset;
 547
 548        tstamp_offset = SST_BYT_TIMESTAMP_OFFSET + str_id * sizeof(fw_tstamp);
 549        memcpy_fromio(&fw_tstamp,
 550                      sst->addr.lpe + tstamp_offset, sizeof(fw_tstamp));
 551
 552        return do_div(fw_tstamp.ring_buffer_counter, buffer_size);
 553}
 554
 555struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt)
 556{
 557        return byt->dsp;
 558}
 559
 560static struct sst_dsp_device byt_dev = {
 561        .thread = sst_byt_irq_thread,
 562        .ops = &sst_byt_ops,
 563};
 564
 565int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata)
 566{
 567        struct sst_byt *byt = pdata->dsp;
 568
 569        dev_dbg(byt->dev, "dsp reset\n");
 570        sst_dsp_reset(byt->dsp);
 571        sst_ipc_drop_all(&byt->ipc);
 572        dev_dbg(byt->dev, "dsp in reset\n");
 573
 574        dev_dbg(byt->dev, "free all blocks and unload fw\n");
 575        sst_fw_unload(byt->fw);
 576
 577        return 0;
 578}
 579EXPORT_SYMBOL_GPL(sst_byt_dsp_suspend_late);
 580
 581int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata)
 582{
 583        struct sst_byt *byt = pdata->dsp;
 584        int ret;
 585
 586        dev_dbg(byt->dev, "reload dsp fw\n");
 587
 588        sst_dsp_reset(byt->dsp);
 589
 590        ret = sst_fw_reload(byt->fw);
 591        if (ret <  0) {
 592                dev_err(dev, "error: failed to reload firmware\n");
 593                return ret;
 594        }
 595
 596        /* wait for DSP boot completion */
 597        byt->boot_complete = false;
 598        sst_dsp_boot(byt->dsp);
 599        dev_dbg(byt->dev, "dsp booting...\n");
 600
 601        return 0;
 602}
 603EXPORT_SYMBOL_GPL(sst_byt_dsp_boot);
 604
 605int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata)
 606{
 607        struct sst_byt *byt = pdata->dsp;
 608        int err;
 609
 610        dev_dbg(byt->dev, "wait for dsp reboot\n");
 611
 612        err = wait_event_timeout(byt->boot_wait, byt->boot_complete,
 613                                 msecs_to_jiffies(IPC_BOOT_MSECS));
 614        if (err == 0) {
 615                dev_err(byt->dev, "ipc: error DSP boot timeout\n");
 616                return -EIO;
 617        }
 618
 619        dev_dbg(byt->dev, "dsp rebooted\n");
 620        return 0;
 621}
 622EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready);
 623
 624static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
 625{
 626        if (msg->header & IPC_HEADER_LARGE(true))
 627                sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
 628
 629        sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->header);
 630}
 631
 632static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
 633{
 634        struct sst_dsp *sst = ipc->dsp;
 635        u64 isr, ipcd, imrx, ipcx;
 636
 637        ipcx = sst_dsp_shim_read64_unlocked(sst, SST_IPCX);
 638        isr = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
 639        ipcd = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
 640        imrx = sst_dsp_shim_read64_unlocked(sst, SST_IMRX);
 641
 642        dev_err(ipc->dev,
 643                "ipc: --%s-- ipcx 0x%llx isr 0x%llx ipcd 0x%llx imrx 0x%llx\n",
 644                text, ipcx, isr, ipcd, imrx);
 645}
 646
 647static void byt_tx_data_copy(struct ipc_message *msg, char *tx_data,
 648        size_t tx_size)
 649{
 650        /* msg content = lower 32-bit of the header + data */
 651        *(u32 *)msg->tx_data = (u32)(msg->header & (u32)-1);
 652        memcpy(msg->tx_data + sizeof(u32), tx_data, tx_size);
 653        msg->tx_size += sizeof(u32);
 654}
 655
 656static u64 byt_reply_msg_match(u64 header, u64 *mask)
 657{
 658        /* match reply to message sent based on msg and stream IDs */
 659        *mask = IPC_HEADER_MSG_ID_MASK |
 660               IPC_HEADER_STR_ID_MASK << IPC_HEADER_STR_ID_SHIFT;
 661        header &= *mask;
 662
 663        return header;
 664}
 665
 666static bool byt_is_dsp_busy(struct sst_dsp *dsp)
 667{
 668        u64 ipcx;
 669
 670        ipcx = sst_dsp_shim_read_unlocked(dsp, SST_IPCX);
 671        return (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE));
 672}
 673
 674int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)
 675{
 676        struct sst_byt *byt;
 677        struct sst_generic_ipc *ipc;
 678        struct sst_fw *byt_sst_fw;
 679        struct sst_byt_fw_init init;
 680        int err;
 681
 682        dev_dbg(dev, "initialising Byt DSP IPC\n");
 683
 684        byt = devm_kzalloc(dev, sizeof(*byt), GFP_KERNEL);
 685        if (byt == NULL)
 686                return -ENOMEM;
 687
 688        byt->dev = dev;
 689
 690        ipc = &byt->ipc;
 691        ipc->dev = dev;
 692        ipc->ops.tx_msg = byt_tx_msg;
 693        ipc->ops.shim_dbg = byt_shim_dbg;
 694        ipc->ops.tx_data_copy = byt_tx_data_copy;
 695        ipc->ops.reply_msg_match = byt_reply_msg_match;
 696        ipc->ops.is_dsp_busy = byt_is_dsp_busy;
 697        ipc->tx_data_max_size = IPC_MAX_MAILBOX_BYTES;
 698        ipc->rx_data_max_size = IPC_MAX_MAILBOX_BYTES;
 699
 700        err = sst_ipc_init(ipc);
 701        if (err != 0)
 702                goto ipc_init_err;
 703
 704        INIT_LIST_HEAD(&byt->stream_list);
 705        init_waitqueue_head(&byt->boot_wait);
 706        byt_dev.thread_context = byt;
 707
 708        /* init SST shim */
 709        byt->dsp = sst_dsp_new(dev, &byt_dev, pdata);
 710        if (byt->dsp == NULL) {
 711                err = -ENODEV;
 712                goto dsp_new_err;
 713        }
 714
 715        ipc->dsp = byt->dsp;
 716
 717        /* keep the DSP in reset state for base FW loading */
 718        sst_dsp_reset(byt->dsp);
 719
 720        byt_sst_fw = sst_fw_new(byt->dsp, pdata->fw, byt);
 721        if (byt_sst_fw  == NULL) {
 722                err = -ENODEV;
 723                dev_err(dev, "error: failed to load firmware\n");
 724                goto fw_err;
 725        }
 726
 727        /* wait for DSP boot completion */
 728        sst_dsp_boot(byt->dsp);
 729        err = wait_event_timeout(byt->boot_wait, byt->boot_complete,
 730                                 msecs_to_jiffies(IPC_BOOT_MSECS));
 731        if (err == 0) {
 732                err = -EIO;
 733                dev_err(byt->dev, "ipc: error DSP boot timeout\n");
 734                goto boot_err;
 735        }
 736
 737        /* show firmware information */
 738        sst_dsp_inbox_read(byt->dsp, &init, sizeof(init));
 739        dev_info(byt->dev, "FW version: %02x.%02x.%02x.%02x\n",
 740                 init.fw_version.major, init.fw_version.minor,
 741                 init.fw_version.build, init.fw_version.type);
 742        dev_info(byt->dev, "Build type: %x\n", init.fw_version.type);
 743        dev_info(byt->dev, "Build date: %s %s\n",
 744                 init.build_info.date, init.build_info.time);
 745
 746        pdata->dsp = byt;
 747        byt->fw = byt_sst_fw;
 748
 749        return 0;
 750
 751boot_err:
 752        sst_dsp_reset(byt->dsp);
 753        sst_fw_free(byt_sst_fw);
 754fw_err:
 755        sst_dsp_free(byt->dsp);
 756dsp_new_err:
 757        sst_ipc_fini(ipc);
 758ipc_init_err:
 759
 760        return err;
 761}
 762EXPORT_SYMBOL_GPL(sst_byt_dsp_init);
 763
 764void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata)
 765{
 766        struct sst_byt *byt = pdata->dsp;
 767
 768        sst_dsp_reset(byt->dsp);
 769        sst_fw_free_all(byt->dsp);
 770        sst_dsp_free(byt->dsp);
 771        sst_ipc_fini(&byt->ipc);
 772}
 773EXPORT_SYMBOL_GPL(sst_byt_dsp_free);
 774