linux/sound/pci/asihpi/hpi6205.c
<<
>>
Prefs
   1/******************************************************************************
   2
   3    AudioScience HPI driver
   4    Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
   5
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of version 2 of the GNU General Public License as
   8    published by the Free Software Foundation;
   9
  10    This program is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU General Public License for more details.
  14
  15    You should have received a copy of the GNU General Public License
  16    along with this program; if not, write to the Free Software
  17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18
  19 Hardware Programming Interface (HPI) for AudioScience
  20 ASI50xx, AS51xx, ASI6xxx, ASI87xx ASI89xx series adapters.
  21 These PCI and PCIe bus adapters are based on a
  22 TMS320C6205 PCI bus mastering DSP,
  23 and (except ASI50xx) TI TMS320C6xxx floating point DSP
  24
  25 Exported function:
  26 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
  27
  28(C) Copyright AudioScience Inc. 1998-2010
  29*******************************************************************************/
  30#define SOURCEFILE_NAME "hpi6205.c"
  31
  32#include "hpi_internal.h"
  33#include "hpimsginit.h"
  34#include "hpidebug.h"
  35#include "hpi6205.h"
  36#include "hpidspcd.h"
  37#include "hpicmn.h"
  38
  39/*****************************************************************************/
  40/* HPI6205 specific error codes */
  41#define HPI6205_ERROR_BASE                      1000
  42/*#define HPI6205_ERROR_MEM_ALLOC 1001 */
  43#define HPI6205_ERROR_6205_NO_IRQ               1002
  44#define HPI6205_ERROR_6205_INIT_FAILED          1003
  45/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
  46#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE        1005
  47#define HPI6205_ERROR_6205_REG                  1006
  48#define HPI6205_ERROR_6205_DSPPAGE              1007
  49#define HPI6205_ERROR_BAD_DSPINDEX              1008
  50#define HPI6205_ERROR_C6713_HPIC                1009
  51#define HPI6205_ERROR_C6713_HPIA                1010
  52#define HPI6205_ERROR_C6713_PLL                 1011
  53#define HPI6205_ERROR_DSP_INTMEM                1012
  54#define HPI6205_ERROR_DSP_EXTMEM                1013
  55#define HPI6205_ERROR_DSP_PLD                   1014
  56#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT     1015
  57#define HPI6205_ERROR_MSG_RESP_TIMEOUT          1016
  58#define HPI6205_ERROR_6205_EEPROM               1017
  59#define HPI6205_ERROR_DSP_EMIF                  1018
  60
  61#define hpi6205_error(dsp_index, err) (err)
  62/*****************************************************************************/
  63/* for C6205 PCI i/f */
  64/* Host Status Register (HSR) bitfields */
  65#define C6205_HSR_INTSRC        0x01
  66#define C6205_HSR_INTAVAL       0x02
  67#define C6205_HSR_INTAM         0x04
  68#define C6205_HSR_CFGERR        0x08
  69#define C6205_HSR_EEREAD        0x10
  70/* Host-to-DSP Control Register (HDCR) bitfields */
  71#define C6205_HDCR_WARMRESET    0x01
  72#define C6205_HDCR_DSPINT       0x02
  73#define C6205_HDCR_PCIBOOT      0x04
  74/* DSP Page Register (DSPP) bitfields, */
  75/* defines 4 Mbyte page that BAR0 points to */
  76#define C6205_DSPP_MAP1         0x400
  77
  78/* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
  79 * BAR1 maps to non-prefetchable 8 Mbyte memory block
  80 * of DSP memory mapped registers (starting at 0x01800000).
  81 * 0x01800000 is hardcoded in the PCI i/f, so that only the offset from this
  82 * needs to be added to the BAR1 base address set in the PCI config reg
  83 */
  84#define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
  85#define C6205_BAR1_HSR  (C6205_BAR1_PCI_IO_OFFSET)
  86#define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
  87#define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
  88
  89/* used to control LED (revA) and reset C6713 (revB) */
  90#define C6205_BAR0_TIMER1_CTL (0x01980000L)
  91
  92/* For first 6713 in CE1 space, using DA17,16,2 */
  93#define HPICL_ADDR      0x01400000L
  94#define HPICH_ADDR      0x01400004L
  95#define HPIAL_ADDR      0x01410000L
  96#define HPIAH_ADDR      0x01410004L
  97#define HPIDIL_ADDR     0x01420000L
  98#define HPIDIH_ADDR     0x01420004L
  99#define HPIDL_ADDR      0x01430000L
 100#define HPIDH_ADDR      0x01430004L
 101
 102#define C6713_EMIF_GCTL         0x01800000
 103#define C6713_EMIF_CE1          0x01800004
 104#define C6713_EMIF_CE0          0x01800008
 105#define C6713_EMIF_CE2          0x01800010
 106#define C6713_EMIF_CE3          0x01800014
 107#define C6713_EMIF_SDRAMCTL     0x01800018
 108#define C6713_EMIF_SDRAMTIMING  0x0180001C
 109#define C6713_EMIF_SDRAMEXT     0x01800020
 110
 111struct hpi_hw_obj {
 112        /* PCI registers */
 113        __iomem u32 *prHSR;
 114        __iomem u32 *prHDCR;
 115        __iomem u32 *prDSPP;
 116
 117        u32 dsp_page;
 118
 119        struct consistent_dma_area h_locked_mem;
 120        struct bus_master_interface *p_interface_buffer;
 121
 122        u16 flag_outstream_just_reset[HPI_MAX_STREAMS];
 123        /* a non-NULL handle means there is an HPI allocated buffer */
 124        struct consistent_dma_area instream_host_buffers[HPI_MAX_STREAMS];
 125        struct consistent_dma_area outstream_host_buffers[HPI_MAX_STREAMS];
 126        /* non-zero size means a buffer exists, may be external */
 127        u32 instream_host_buffer_size[HPI_MAX_STREAMS];
 128        u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
 129
 130        struct consistent_dma_area h_control_cache;
 131        struct consistent_dma_area h_async_event_buffer;
 132/*      struct hpi_control_cache_single *pControlCache; */
 133        struct hpi_async_event *p_async_event_buffer;
 134        struct hpi_control_cache *p_cache;
 135};
 136
 137/*****************************************************************************/
 138/* local prototypes */
 139
 140#define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
 141
 142static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us);
 143
 144static void send_dsp_command(struct hpi_hw_obj *phw, int cmd);
 145
 146static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
 147        u32 *pos_error_code);
 148
 149static u16 message_response_sequence(struct hpi_adapter_obj *pao,
 150        struct hpi_message *phm, struct hpi_response *phr);
 151
 152static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
 153        struct hpi_response *phr);
 154
 155#define HPI6205_TIMEOUT 1000000
 156
 157static void subsys_create_adapter(struct hpi_message *phm,
 158        struct hpi_response *phr);
 159static void subsys_delete_adapter(struct hpi_message *phm,
 160        struct hpi_response *phr);
 161
 162static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
 163        u32 *pos_error_code);
 164
 165static void delete_adapter_obj(struct hpi_adapter_obj *pao);
 166
 167static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
 168        struct hpi_message *phm, struct hpi_response *phr);
 169
 170static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
 171        struct hpi_message *phm, struct hpi_response *phr);
 172
 173static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
 174        struct hpi_message *phm, struct hpi_response *phr);
 175static void outstream_write(struct hpi_adapter_obj *pao,
 176        struct hpi_message *phm, struct hpi_response *phr);
 177
 178static void outstream_get_info(struct hpi_adapter_obj *pao,
 179        struct hpi_message *phm, struct hpi_response *phr);
 180
 181static void outstream_start(struct hpi_adapter_obj *pao,
 182        struct hpi_message *phm, struct hpi_response *phr);
 183
 184static void outstream_open(struct hpi_adapter_obj *pao,
 185        struct hpi_message *phm, struct hpi_response *phr);
 186
 187static void outstream_reset(struct hpi_adapter_obj *pao,
 188        struct hpi_message *phm, struct hpi_response *phr);
 189
 190static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
 191        struct hpi_message *phm, struct hpi_response *phr);
 192
 193static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
 194        struct hpi_message *phm, struct hpi_response *phr);
 195
 196static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
 197        struct hpi_message *phm, struct hpi_response *phr);
 198
 199static void instream_read(struct hpi_adapter_obj *pao,
 200        struct hpi_message *phm, struct hpi_response *phr);
 201
 202static void instream_get_info(struct hpi_adapter_obj *pao,
 203        struct hpi_message *phm, struct hpi_response *phr);
 204
 205static void instream_start(struct hpi_adapter_obj *pao,
 206        struct hpi_message *phm, struct hpi_response *phr);
 207
 208static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
 209        u32 address);
 210
 211static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
 212        u32 address, u32 data);
 213
 214static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
 215        int dsp_index);
 216
 217static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
 218        u32 address, u32 length);
 219
 220static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
 221        int dsp_index);
 222
 223static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
 224        int dsp_index);
 225
 226static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
 227
 228/*****************************************************************************/
 229
 230static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
 231{
 232
 233        switch (phm->function) {
 234        case HPI_SUBSYS_OPEN:
 235        case HPI_SUBSYS_CLOSE:
 236        case HPI_SUBSYS_GET_INFO:
 237        case HPI_SUBSYS_DRIVER_UNLOAD:
 238        case HPI_SUBSYS_DRIVER_LOAD:
 239        case HPI_SUBSYS_FIND_ADAPTERS:
 240                /* messages that should not get here */
 241                phr->error = HPI_ERROR_UNIMPLEMENTED;
 242                break;
 243        case HPI_SUBSYS_CREATE_ADAPTER:
 244                subsys_create_adapter(phm, phr);
 245                break;
 246        case HPI_SUBSYS_DELETE_ADAPTER:
 247                subsys_delete_adapter(phm, phr);
 248                break;
 249        default:
 250                phr->error = HPI_ERROR_INVALID_FUNC;
 251                break;
 252        }
 253}
 254
 255static void control_message(struct hpi_adapter_obj *pao,
 256        struct hpi_message *phm, struct hpi_response *phr)
 257{
 258
 259        struct hpi_hw_obj *phw = pao->priv;
 260
 261        switch (phm->function) {
 262        case HPI_CONTROL_GET_STATE:
 263                if (pao->has_control_cache) {
 264                        rmb();  /* make sure we see updates DM_aed from DSP */
 265                        if (hpi_check_control_cache(phw->p_cache, phm, phr))
 266                                break;
 267                }
 268                hw_message(pao, phm, phr);
 269                break;
 270        case HPI_CONTROL_GET_INFO:
 271                hw_message(pao, phm, phr);
 272                break;
 273        case HPI_CONTROL_SET_STATE:
 274                hw_message(pao, phm, phr);
 275                if (pao->has_control_cache)
 276                        hpi_sync_control_cache(phw->p_cache, phm, phr);
 277                break;
 278        default:
 279                phr->error = HPI_ERROR_INVALID_FUNC;
 280                break;
 281        }
 282}
 283
 284static void adapter_message(struct hpi_adapter_obj *pao,
 285        struct hpi_message *phm, struct hpi_response *phr)
 286{
 287        switch (phm->function) {
 288        default:
 289                hw_message(pao, phm, phr);
 290                break;
 291        }
 292}
 293
 294static void outstream_message(struct hpi_adapter_obj *pao,
 295        struct hpi_message *phm, struct hpi_response *phr)
 296{
 297
 298        if (phm->obj_index >= HPI_MAX_STREAMS) {
 299                phr->error = HPI_ERROR_INVALID_STREAM;
 300                HPI_DEBUG_LOG(WARNING,
 301                        "message referencing invalid stream %d "
 302                        "on adapter index %d\n", phm->obj_index,
 303                        phm->adapter_index);
 304                return;
 305        }
 306
 307        switch (phm->function) {
 308        case HPI_OSTREAM_WRITE:
 309                outstream_write(pao, phm, phr);
 310                break;
 311        case HPI_OSTREAM_GET_INFO:
 312                outstream_get_info(pao, phm, phr);
 313                break;
 314        case HPI_OSTREAM_HOSTBUFFER_ALLOC:
 315                outstream_host_buffer_allocate(pao, phm, phr);
 316                break;
 317        case HPI_OSTREAM_HOSTBUFFER_GET_INFO:
 318                outstream_host_buffer_get_info(pao, phm, phr);
 319                break;
 320        case HPI_OSTREAM_HOSTBUFFER_FREE:
 321                outstream_host_buffer_free(pao, phm, phr);
 322                break;
 323        case HPI_OSTREAM_START:
 324                outstream_start(pao, phm, phr);
 325                break;
 326        case HPI_OSTREAM_OPEN:
 327                outstream_open(pao, phm, phr);
 328                break;
 329        case HPI_OSTREAM_RESET:
 330                outstream_reset(pao, phm, phr);
 331                break;
 332        default:
 333                hw_message(pao, phm, phr);
 334                break;
 335        }
 336}
 337
 338static void instream_message(struct hpi_adapter_obj *pao,
 339        struct hpi_message *phm, struct hpi_response *phr)
 340{
 341
 342        if (phm->obj_index >= HPI_MAX_STREAMS) {
 343                phr->error = HPI_ERROR_INVALID_STREAM;
 344                HPI_DEBUG_LOG(WARNING,
 345                        "message referencing invalid stream %d "
 346                        "on adapter index %d\n", phm->obj_index,
 347                        phm->adapter_index);
 348                return;
 349        }
 350
 351        switch (phm->function) {
 352        case HPI_ISTREAM_READ:
 353                instream_read(pao, phm, phr);
 354                break;
 355        case HPI_ISTREAM_GET_INFO:
 356                instream_get_info(pao, phm, phr);
 357                break;
 358        case HPI_ISTREAM_HOSTBUFFER_ALLOC:
 359                instream_host_buffer_allocate(pao, phm, phr);
 360                break;
 361        case HPI_ISTREAM_HOSTBUFFER_GET_INFO:
 362                instream_host_buffer_get_info(pao, phm, phr);
 363                break;
 364        case HPI_ISTREAM_HOSTBUFFER_FREE:
 365                instream_host_buffer_free(pao, phm, phr);
 366                break;
 367        case HPI_ISTREAM_START:
 368                instream_start(pao, phm, phr);
 369                break;
 370        default:
 371                hw_message(pao, phm, phr);
 372                break;
 373        }
 374}
 375
 376/*****************************************************************************/
 377/** Entry point to this HPI backend
 378 * All calls to the HPI start here
 379 */
 380void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
 381{
 382        struct hpi_adapter_obj *pao = NULL;
 383
 384        /* subsytem messages are processed by every HPI.
 385         * All other messages are ignored unless the adapter index matches
 386         * an adapter in the HPI
 387         */
 388        HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object,
 389                phm->function);
 390
 391        /* if Dsp has crashed then do not communicate with it any more */
 392        if (phm->object != HPI_OBJ_SUBSYSTEM) {
 393                pao = hpi_find_adapter(phm->adapter_index);
 394                if (!pao) {
 395                        HPI_DEBUG_LOG(DEBUG,
 396                                " %d,%d refused, for another HPI?\n",
 397                                phm->object, phm->function);
 398                        return;
 399                }
 400
 401                if ((pao->dsp_crashed >= 10)
 402                        && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
 403                        /* allow last resort debug read even after crash */
 404                        hpi_init_response(phr, phm->object, phm->function,
 405                                HPI_ERROR_DSP_HARDWARE);
 406                        HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
 407                                phm->object, phm->function);
 408                        return;
 409                }
 410        }
 411
 412        /* Init default response  */
 413        if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
 414                hpi_init_response(phr, phm->object, phm->function,
 415                        HPI_ERROR_PROCESSING_MESSAGE);
 416
 417        HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
 418        switch (phm->type) {
 419        case HPI_TYPE_MESSAGE:
 420                switch (phm->object) {
 421                case HPI_OBJ_SUBSYSTEM:
 422                        subsys_message(phm, phr);
 423                        break;
 424
 425                case HPI_OBJ_ADAPTER:
 426                        phr->size =
 427                                sizeof(struct hpi_response_header) +
 428                                sizeof(struct hpi_adapter_res);
 429                        adapter_message(pao, phm, phr);
 430                        break;
 431
 432                case HPI_OBJ_CONTROLEX:
 433                case HPI_OBJ_CONTROL:
 434                        control_message(pao, phm, phr);
 435                        break;
 436
 437                case HPI_OBJ_OSTREAM:
 438                        outstream_message(pao, phm, phr);
 439                        break;
 440
 441                case HPI_OBJ_ISTREAM:
 442                        instream_message(pao, phm, phr);
 443                        break;
 444
 445                default:
 446                        hw_message(pao, phm, phr);
 447                        break;
 448                }
 449                break;
 450
 451        default:
 452                phr->error = HPI_ERROR_INVALID_TYPE;
 453                break;
 454        }
 455}
 456
 457/*****************************************************************************/
 458/* SUBSYSTEM */
 459
 460/** Create an adapter object and initialise it based on resource information
 461 * passed in in the message
 462 * *** NOTE - you cannot use this function AND the FindAdapters function at the
 463 * same time, the application must use only one of them to get the adapters ***
 464 */
 465static void subsys_create_adapter(struct hpi_message *phm,
 466        struct hpi_response *phr)
 467{
 468        /* create temp adapter obj, because we don't know what index yet */
 469        struct hpi_adapter_obj ao;
 470        u32 os_error_code;
 471        u16 err;
 472
 473        HPI_DEBUG_LOG(DEBUG, " subsys_create_adapter\n");
 474
 475        memset(&ao, 0, sizeof(ao));
 476
 477        /* this HPI only creates adapters for TI/PCI devices */
 478        if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
 479                return;
 480        if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
 481                return;
 482        if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205)
 483                return;
 484
 485        ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
 486        if (!ao.priv) {
 487                HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
 488                phr->error = HPI_ERROR_MEMORY_ALLOC;
 489                return;
 490        }
 491
 492        ao.pci = *phm->u.s.resource.r.pci;
 493        err = create_adapter_obj(&ao, &os_error_code);
 494        if (!err)
 495                err = hpi_add_adapter(&ao);
 496        if (err) {
 497                phr->u.s.data = os_error_code;
 498                delete_adapter_obj(&ao);
 499                phr->error = err;
 500                return;
 501        }
 502
 503        phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
 504        phr->u.s.adapter_index = ao.index;
 505        phr->u.s.num_adapters++;
 506        phr->error = 0;
 507}
 508
 509/** delete an adapter - required by WDM driver */
 510static void subsys_delete_adapter(struct hpi_message *phm,
 511        struct hpi_response *phr)
 512{
 513        struct hpi_adapter_obj *pao;
 514        struct hpi_hw_obj *phw;
 515
 516        pao = hpi_find_adapter(phm->adapter_index);
 517        if (!pao) {
 518                phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
 519                return;
 520        }
 521        phw = (struct hpi_hw_obj *)pao->priv;
 522        /* reset adapter h/w */
 523        /* Reset C6713 #1 */
 524        boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
 525        /* reset C6205 */
 526        iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
 527
 528        delete_adapter_obj(pao);
 529        phr->error = 0;
 530}
 531
 532/** Create adapter object
 533  allocate buffers, bootload DSPs, initialise control cache
 534*/
 535static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
 536        u32 *pos_error_code)
 537{
 538        struct hpi_hw_obj *phw = pao->priv;
 539        struct bus_master_interface *interface;
 540        u32 phys_addr;
 541#ifndef HPI6205_NO_HSR_POLL
 542        u32 time_out = HPI6205_TIMEOUT;
 543        u32 temp1;
 544#endif
 545        int i;
 546        u16 err;
 547
 548        /* init error reporting */
 549        pao->dsp_crashed = 0;
 550
 551        for (i = 0; i < HPI_MAX_STREAMS; i++)
 552                phw->flag_outstream_just_reset[i] = 1;
 553
 554        /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
 555        phw->prHSR =
 556                pao->pci.ap_mem_base[1] +
 557                C6205_BAR1_HSR / sizeof(*pao->pci.ap_mem_base[1]);
 558        phw->prHDCR =
 559                pao->pci.ap_mem_base[1] +
 560                C6205_BAR1_HDCR / sizeof(*pao->pci.ap_mem_base[1]);
 561        phw->prDSPP =
 562                pao->pci.ap_mem_base[1] +
 563                C6205_BAR1_DSPP / sizeof(*pao->pci.ap_mem_base[1]);
 564
 565        pao->has_control_cache = 0;
 566
 567        if (hpios_locked_mem_alloc(&phw->h_locked_mem,
 568                        sizeof(struct bus_master_interface),
 569                        pao->pci.p_os_data))
 570                phw->p_interface_buffer = NULL;
 571        else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
 572                        (void *)&phw->p_interface_buffer))
 573                phw->p_interface_buffer = NULL;
 574
 575        HPI_DEBUG_LOG(DEBUG, "interface buffer address %p\n",
 576                phw->p_interface_buffer);
 577
 578        if (phw->p_interface_buffer) {
 579                memset((void *)phw->p_interface_buffer, 0,
 580                        sizeof(struct bus_master_interface));
 581                phw->p_interface_buffer->dsp_ack = H620_HIF_UNKNOWN;
 582        }
 583
 584        err = adapter_boot_load_dsp(pao, pos_error_code);
 585        if (err)
 586                /* no need to clean up as SubSysCreateAdapter */
 587                /* calls DeleteAdapter on error. */
 588                return err;
 589
 590        HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
 591
 592        /* allow boot load even if mem alloc wont work */
 593        if (!phw->p_interface_buffer)
 594                return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC);
 595
 596        interface = phw->p_interface_buffer;
 597
 598#ifndef HPI6205_NO_HSR_POLL
 599        /* wait for first interrupt indicating the DSP init is done */
 600        time_out = HPI6205_TIMEOUT * 10;
 601        temp1 = 0;
 602        while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out)
 603                temp1 = ioread32(phw->prHSR);
 604
 605        if (temp1 & C6205_HSR_INTSRC)
 606                HPI_DEBUG_LOG(INFO,
 607                        "interrupt confirming DSP code running OK\n");
 608        else {
 609                HPI_DEBUG_LOG(ERROR,
 610                        "timed out waiting for interrupt "
 611                        "confirming DSP code running\n");
 612                return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
 613        }
 614
 615        /* reset the interrupt */
 616        iowrite32(C6205_HSR_INTSRC, phw->prHSR);
 617#endif
 618
 619        /* make sure the DSP has started ok */
 620        if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
 621                HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
 622                return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED);
 623        }
 624        /* Note that *pao, *phw are zeroed after allocation,
 625         * so pointers and flags are NULL by default.
 626         * Allocate bus mastering control cache buffer and tell the DSP about it
 627         */
 628        if (interface->control_cache.number_of_controls) {
 629                void *p_control_cache_virtual;
 630
 631                err = hpios_locked_mem_alloc(&phw->h_control_cache,
 632                        interface->control_cache.size_in_bytes,
 633                        pao->pci.p_os_data);
 634                if (!err)
 635                        err = hpios_locked_mem_get_virt_addr(&phw->
 636                                h_control_cache, &p_control_cache_virtual);
 637                if (!err) {
 638                        memset(p_control_cache_virtual, 0,
 639                                interface->control_cache.size_in_bytes);
 640
 641                        phw->p_cache =
 642                                hpi_alloc_control_cache(interface->
 643                                control_cache.number_of_controls,
 644                                interface->control_cache.size_in_bytes,
 645                                (struct hpi_control_cache_info *)
 646                                p_control_cache_virtual);
 647                        if (!phw->p_cache)
 648                                err = HPI_ERROR_MEMORY_ALLOC;
 649                }
 650                if (!err) {
 651                        err = hpios_locked_mem_get_phys_addr(&phw->
 652                                h_control_cache, &phys_addr);
 653                        interface->control_cache.physical_address32 =
 654                                phys_addr;
 655                }
 656
 657                if (!err)
 658                        pao->has_control_cache = 1;
 659                else {
 660                        if (hpios_locked_mem_valid(&phw->h_control_cache))
 661                                hpios_locked_mem_free(&phw->h_control_cache);
 662                        pao->has_control_cache = 0;
 663                }
 664        }
 665        /* allocate bus mastering async buffer and tell the DSP about it */
 666        if (interface->async_buffer.b.size) {
 667                err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
 668                        interface->async_buffer.b.size *
 669                        sizeof(struct hpi_async_event), pao->pci.p_os_data);
 670                if (!err)
 671                        err = hpios_locked_mem_get_virt_addr
 672                                (&phw->h_async_event_buffer, (void *)
 673                                &phw->p_async_event_buffer);
 674                if (!err)
 675                        memset((void *)phw->p_async_event_buffer, 0,
 676                                interface->async_buffer.b.size *
 677                                sizeof(struct hpi_async_event));
 678                if (!err) {
 679                        err = hpios_locked_mem_get_phys_addr
 680                                (&phw->h_async_event_buffer, &phys_addr);
 681                        interface->async_buffer.physical_address32 =
 682                                phys_addr;
 683                }
 684                if (err) {
 685                        if (hpios_locked_mem_valid(&phw->
 686                                        h_async_event_buffer)) {
 687                                hpios_locked_mem_free
 688                                        (&phw->h_async_event_buffer);
 689                                phw->p_async_event_buffer = NULL;
 690                        }
 691                }
 692        }
 693        send_dsp_command(phw, H620_HIF_IDLE);
 694
 695        {
 696                struct hpi_message hM;
 697                struct hpi_response hR;
 698                u32 max_streams;
 699
 700                HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
 701                memset(&hM, 0, sizeof(hM));
 702                hM.type = HPI_TYPE_MESSAGE;
 703                hM.size = sizeof(hM);
 704                hM.object = HPI_OBJ_ADAPTER;
 705                hM.function = HPI_ADAPTER_GET_INFO;
 706                hM.adapter_index = 0;
 707                memset(&hR, 0, sizeof(hR));
 708                hR.size = sizeof(hR);
 709
 710                err = message_response_sequence(pao, &hM, &hR);
 711                if (err) {
 712                        HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
 713                                err);
 714                        return err;
 715                }
 716                if (hR.error)
 717                        return hR.error;
 718
 719                pao->adapter_type = hR.u.a.adapter_type;
 720                pao->index = hR.u.a.adapter_index;
 721
 722                max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams;
 723
 724                hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
 725                        65536, pao->pci.p_os_data);
 726
 727                HPI_DEBUG_LOG(VERBOSE,
 728                        "got adapter info type %x index %d serial %d\n",
 729                        hR.u.a.adapter_type, hR.u.a.adapter_index,
 730                        hR.u.a.serial_number);
 731        }
 732
 733        pao->open = 0;  /* upon creation the adapter is closed */
 734
 735        HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
 736        return 0;
 737}
 738
 739/** Free memory areas allocated by adapter
 740 * this routine is called from SubSysDeleteAdapter,
 741  * and SubSysCreateAdapter if duplicate index
 742*/
 743static void delete_adapter_obj(struct hpi_adapter_obj *pao)
 744{
 745        struct hpi_hw_obj *phw;
 746        int i;
 747
 748        phw = pao->priv;
 749
 750        if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) {
 751                hpios_locked_mem_free(&phw->h_async_event_buffer);
 752                phw->p_async_event_buffer = NULL;
 753        }
 754
 755        if (hpios_locked_mem_valid(&phw->h_control_cache)) {
 756                hpios_locked_mem_free(&phw->h_control_cache);
 757                hpi_free_control_cache(phw->p_cache);
 758        }
 759
 760        if (hpios_locked_mem_valid(&phw->h_locked_mem)) {
 761                hpios_locked_mem_free(&phw->h_locked_mem);
 762                phw->p_interface_buffer = NULL;
 763        }
 764
 765        for (i = 0; i < HPI_MAX_STREAMS; i++)
 766                if (hpios_locked_mem_valid(&phw->instream_host_buffers[i])) {
 767                        hpios_locked_mem_free(&phw->instream_host_buffers[i]);
 768                        /*?phw->InStreamHostBuffers[i] = NULL; */
 769                        phw->instream_host_buffer_size[i] = 0;
 770                }
 771
 772        for (i = 0; i < HPI_MAX_STREAMS; i++)
 773                if (hpios_locked_mem_valid(&phw->outstream_host_buffers[i])) {
 774                        hpios_locked_mem_free(&phw->outstream_host_buffers
 775                                [i]);
 776                        phw->outstream_host_buffer_size[i] = 0;
 777                }
 778
 779        hpios_locked_mem_unprepare(pao->pci.p_os_data);
 780
 781        hpi_delete_adapter(pao);
 782        kfree(phw);
 783}
 784
 785/*****************************************************************************/
 786/* OutStream Host buffer functions */
 787
 788/** Allocate or attach buffer for busmastering
 789*/
 790static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
 791        struct hpi_message *phm, struct hpi_response *phr)
 792{
 793        u16 err = 0;
 794        u32 command = phm->u.d.u.buffer.command;
 795        struct hpi_hw_obj *phw = pao->priv;
 796        struct bus_master_interface *interface = phw->p_interface_buffer;
 797
 798        hpi_init_response(phr, phm->object, phm->function, 0);
 799
 800        if (command == HPI_BUFFER_CMD_EXTERNAL
 801                || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
 802                /* ALLOC phase, allocate a buffer with power of 2 size,
 803                   get its bus address for PCI bus mastering
 804                 */
 805                phm->u.d.u.buffer.buffer_size =
 806                        roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
 807                /* return old size and allocated size,
 808                   so caller can detect change */
 809                phr->u.d.u.stream_info.data_available =
 810                        phw->outstream_host_buffer_size[phm->obj_index];
 811                phr->u.d.u.stream_info.buffer_size =
 812                        phm->u.d.u.buffer.buffer_size;
 813
 814                if (phw->outstream_host_buffer_size[phm->obj_index] ==
 815                        phm->u.d.u.buffer.buffer_size) {
 816                        /* Same size, no action required */
 817                        return;
 818                }
 819
 820                if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
 821                                        obj_index]))
 822                        hpios_locked_mem_free(&phw->outstream_host_buffers
 823                                [phm->obj_index]);
 824
 825                err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
 826                        [phm->obj_index], phm->u.d.u.buffer.buffer_size,
 827                        pao->pci.p_os_data);
 828
 829                if (err) {
 830                        phr->error = HPI_ERROR_INVALID_DATASIZE;
 831                        phw->outstream_host_buffer_size[phm->obj_index] = 0;
 832                        return;
 833                }
 834
 835                err = hpios_locked_mem_get_phys_addr
 836                        (&phw->outstream_host_buffers[phm->obj_index],
 837                        &phm->u.d.u.buffer.pci_address);
 838                /* get the phys addr into msg for single call alloc caller
 839                 * needs to do this for split alloc (or use the same message)
 840                 * return the phy address for split alloc in the respose too
 841                 */
 842                phr->u.d.u.stream_info.auxiliary_data_available =
 843                        phm->u.d.u.buffer.pci_address;
 844
 845                if (err) {
 846                        hpios_locked_mem_free(&phw->outstream_host_buffers
 847                                [phm->obj_index]);
 848                        phw->outstream_host_buffer_size[phm->obj_index] = 0;
 849                        phr->error = HPI_ERROR_MEMORY_ALLOC;
 850                        return;
 851                }
 852        }
 853
 854        if (command == HPI_BUFFER_CMD_EXTERNAL
 855                || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
 856                /* GRANT phase.  Set up the BBM status, tell the DSP about
 857                   the buffer so it can start using BBM.
 858                 */
 859                struct hpi_hostbuffer_status *status;
 860
 861                if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
 862                                buffer_size - 1)) {
 863                        HPI_DEBUG_LOG(ERROR,
 864                                "buffer size must be 2^N not %d\n",
 865                                phm->u.d.u.buffer.buffer_size);
 866                        phr->error = HPI_ERROR_INVALID_DATASIZE;
 867                        return;
 868                }
 869                phw->outstream_host_buffer_size[phm->obj_index] =
 870                        phm->u.d.u.buffer.buffer_size;
 871                status = &interface->outstream_host_buffer_status[phm->
 872                        obj_index];
 873                status->samples_processed = 0;
 874                status->stream_state = HPI_STATE_STOPPED;
 875                status->dSP_index = 0;
 876                status->host_index = status->dSP_index;
 877                status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
 878
 879                hw_message(pao, phm, phr);
 880
 881                if (phr->error
 882                        && hpios_locked_mem_valid(&phw->
 883                                outstream_host_buffers[phm->obj_index])) {
 884                        hpios_locked_mem_free(&phw->outstream_host_buffers
 885                                [phm->obj_index]);
 886                        phw->outstream_host_buffer_size[phm->obj_index] = 0;
 887                }
 888        }
 889}
 890
 891static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
 892        struct hpi_message *phm, struct hpi_response *phr)
 893{
 894        struct hpi_hw_obj *phw = pao->priv;
 895        struct bus_master_interface *interface = phw->p_interface_buffer;
 896        struct hpi_hostbuffer_status *status;
 897        u8 *p_bbm_data;
 898
 899        if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
 900                                obj_index])) {
 901                if (hpios_locked_mem_get_virt_addr(&phw->
 902                                outstream_host_buffers[phm->obj_index],
 903                                (void *)&p_bbm_data)) {
 904                        phr->error = HPI_ERROR_INVALID_OPERATION;
 905                        return;
 906                }
 907                status = &interface->outstream_host_buffer_status[phm->
 908                        obj_index];
 909                hpi_init_response(phr, HPI_OBJ_OSTREAM,
 910                        HPI_OSTREAM_HOSTBUFFER_GET_INFO, 0);
 911                phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
 912                phr->u.d.u.hostbuffer_info.p_status = status;
 913        } else {
 914                hpi_init_response(phr, HPI_OBJ_OSTREAM,
 915                        HPI_OSTREAM_HOSTBUFFER_GET_INFO,
 916                        HPI_ERROR_INVALID_OPERATION);
 917        }
 918}
 919
 920static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
 921        struct hpi_message *phm, struct hpi_response *phr)
 922{
 923        struct hpi_hw_obj *phw = pao->priv;
 924        u32 command = phm->u.d.u.buffer.command;
 925
 926        if (phw->outstream_host_buffer_size[phm->obj_index]) {
 927                if (command == HPI_BUFFER_CMD_EXTERNAL
 928                        || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
 929                        phw->outstream_host_buffer_size[phm->obj_index] = 0;
 930                        hw_message(pao, phm, phr);
 931                        /* Tell adapter to stop using the host buffer. */
 932                }
 933                if (command == HPI_BUFFER_CMD_EXTERNAL
 934                        || command == HPI_BUFFER_CMD_INTERNAL_FREE)
 935                        hpios_locked_mem_free(&phw->outstream_host_buffers
 936                                [phm->obj_index]);
 937        }
 938        /* Should HPI_ERROR_INVALID_OPERATION be returned
 939           if no host buffer is allocated? */
 940        else
 941                hpi_init_response(phr, HPI_OBJ_OSTREAM,
 942                        HPI_OSTREAM_HOSTBUFFER_FREE, 0);
 943
 944}
 945
 946static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status)
 947{
 948        return status->size_in_bytes - (status->host_index -
 949                status->dSP_index);
 950}
 951
 952static void outstream_write(struct hpi_adapter_obj *pao,
 953        struct hpi_message *phm, struct hpi_response *phr)
 954{
 955        struct hpi_hw_obj *phw = pao->priv;
 956        struct bus_master_interface *interface = phw->p_interface_buffer;
 957        struct hpi_hostbuffer_status *status;
 958        u32 space_available;
 959
 960        if (!phw->outstream_host_buffer_size[phm->obj_index]) {
 961                /* there  is no BBM buffer, write via message */
 962                hw_message(pao, phm, phr);
 963                return;
 964        }
 965
 966        hpi_init_response(phr, phm->object, phm->function, 0);
 967        status = &interface->outstream_host_buffer_status[phm->obj_index];
 968
 969        if (phw->flag_outstream_just_reset[phm->obj_index]) {
 970                /* First OutStremWrite() call following reset will write data to the
 971                   adapter's buffers, reducing delay before stream can start. The DSP
 972                   takes care of setting the stream data format using format information
 973                   embedded in phm.
 974                 */
 975                int partial_write = 0;
 976                unsigned int original_size = 0;
 977
 978                phw->flag_outstream_just_reset[phm->obj_index] = 0;
 979
 980                /* Send the first buffer to the DSP the old way. */
 981                /* Limit size of first transfer - */
 982                /* expect that this will not usually be triggered. */
 983                if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
 984                        partial_write = 1;
 985                        original_size = phm->u.d.u.data.data_size;
 986                        phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
 987                }
 988                /* write it */
 989                phm->function = HPI_OSTREAM_WRITE;
 990                hw_message(pao, phm, phr);
 991
 992                if (phr->error)
 993                        return;
 994
 995                /* update status information that the DSP would typically
 996                 * update (and will update next time the DSP
 997                 * buffer update task reads data from the host BBM buffer)
 998                 */
 999                status->auxiliary_data_available = phm->u.d.u.data.data_size;
1000                status->host_index += phm->u.d.u.data.data_size;
1001                status->dSP_index += phm->u.d.u.data.data_size;
1002
1003                /* if we did a full write, we can return from here. */
1004                if (!partial_write)
1005                        return;
1006
1007                /* tweak buffer parameters and let the rest of the */
1008                /* buffer land in internal BBM buffer */
1009                phm->u.d.u.data.data_size =
1010                        original_size - HPI6205_SIZEOF_DATA;
1011                phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1012        }
1013
1014        space_available = outstream_get_space_available(status);
1015        if (space_available < phm->u.d.u.data.data_size) {
1016                phr->error = HPI_ERROR_INVALID_DATASIZE;
1017                return;
1018        }
1019
1020        /* HostBuffers is used to indicate host buffer is internally allocated.
1021           otherwise, assumed external, data written externally */
1022        if (phm->u.d.u.data.pb_data
1023                && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
1024                                obj_index])) {
1025                u8 *p_bbm_data;
1026                u32 l_first_write;
1027                u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1028
1029                if (hpios_locked_mem_get_virt_addr(&phw->
1030                                outstream_host_buffers[phm->obj_index],
1031                                (void *)&p_bbm_data)) {
1032                        phr->error = HPI_ERROR_INVALID_OPERATION;
1033                        return;
1034                }
1035
1036                /* either all data,
1037                   or enough to fit from current to end of BBM buffer */
1038                l_first_write =
1039                        min(phm->u.d.u.data.data_size,
1040                        status->size_in_bytes -
1041                        (status->host_index & (status->size_in_bytes - 1)));
1042
1043                memcpy(p_bbm_data +
1044                        (status->host_index & (status->size_in_bytes - 1)),
1045                        p_app_data, l_first_write);
1046                /* remaining data if any */
1047                memcpy(p_bbm_data, p_app_data + l_first_write,
1048                        phm->u.d.u.data.data_size - l_first_write);
1049        }
1050        status->host_index += phm->u.d.u.data.data_size;
1051}
1052
1053static void outstream_get_info(struct hpi_adapter_obj *pao,
1054        struct hpi_message *phm, struct hpi_response *phr)
1055{
1056        struct hpi_hw_obj *phw = pao->priv;
1057        struct bus_master_interface *interface = phw->p_interface_buffer;
1058        struct hpi_hostbuffer_status *status;
1059
1060        if (!phw->outstream_host_buffer_size[phm->obj_index]) {
1061                hw_message(pao, phm, phr);
1062                return;
1063        }
1064
1065        hpi_init_response(phr, phm->object, phm->function, 0);
1066
1067        status = &interface->outstream_host_buffer_status[phm->obj_index];
1068
1069        phr->u.d.u.stream_info.state = (u16)status->stream_state;
1070        phr->u.d.u.stream_info.samples_transferred =
1071                status->samples_processed;
1072        phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1073        phr->u.d.u.stream_info.data_available =
1074                status->size_in_bytes - outstream_get_space_available(status);
1075        phr->u.d.u.stream_info.auxiliary_data_available =
1076                status->auxiliary_data_available;
1077}
1078
1079static void outstream_start(struct hpi_adapter_obj *pao,
1080        struct hpi_message *phm, struct hpi_response *phr)
1081{
1082        hw_message(pao, phm, phr);
1083}
1084
1085static void outstream_reset(struct hpi_adapter_obj *pao,
1086        struct hpi_message *phm, struct hpi_response *phr)
1087{
1088        struct hpi_hw_obj *phw = pao->priv;
1089        phw->flag_outstream_just_reset[phm->obj_index] = 1;
1090        hw_message(pao, phm, phr);
1091}
1092
1093static void outstream_open(struct hpi_adapter_obj *pao,
1094        struct hpi_message *phm, struct hpi_response *phr)
1095{
1096        outstream_reset(pao, phm, phr);
1097}
1098
1099/*****************************************************************************/
1100/* InStream Host buffer functions */
1101
1102static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1103        struct hpi_message *phm, struct hpi_response *phr)
1104{
1105        u16 err = 0;
1106        u32 command = phm->u.d.u.buffer.command;
1107        struct hpi_hw_obj *phw = pao->priv;
1108        struct bus_master_interface *interface = phw->p_interface_buffer;
1109
1110        hpi_init_response(phr, phm->object, phm->function, 0);
1111
1112        if (command == HPI_BUFFER_CMD_EXTERNAL
1113                || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
1114
1115                phm->u.d.u.buffer.buffer_size =
1116                        roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
1117                phr->u.d.u.stream_info.data_available =
1118                        phw->instream_host_buffer_size[phm->obj_index];
1119                phr->u.d.u.stream_info.buffer_size =
1120                        phm->u.d.u.buffer.buffer_size;
1121
1122                if (phw->instream_host_buffer_size[phm->obj_index] ==
1123                        phm->u.d.u.buffer.buffer_size) {
1124                        /* Same size, no action required */
1125                        return;
1126                }
1127
1128                if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1129                                        obj_index]))
1130                        hpios_locked_mem_free(&phw->instream_host_buffers
1131                                [phm->obj_index]);
1132
1133                err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1134                                obj_index], phm->u.d.u.buffer.buffer_size,
1135                        pao->pci.p_os_data);
1136
1137                if (err) {
1138                        phr->error = HPI_ERROR_INVALID_DATASIZE;
1139                        phw->instream_host_buffer_size[phm->obj_index] = 0;
1140                        return;
1141                }
1142
1143                err = hpios_locked_mem_get_phys_addr
1144                        (&phw->instream_host_buffers[phm->obj_index],
1145                        &phm->u.d.u.buffer.pci_address);
1146                /* get the phys addr into msg for single call alloc. Caller
1147                   needs to do this for split alloc so return the phy address */
1148                phr->u.d.u.stream_info.auxiliary_data_available =
1149                        phm->u.d.u.buffer.pci_address;
1150                if (err) {
1151                        hpios_locked_mem_free(&phw->instream_host_buffers
1152                                [phm->obj_index]);
1153                        phw->instream_host_buffer_size[phm->obj_index] = 0;
1154                        phr->error = HPI_ERROR_MEMORY_ALLOC;
1155                        return;
1156                }
1157        }
1158
1159        if (command == HPI_BUFFER_CMD_EXTERNAL
1160                || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
1161                struct hpi_hostbuffer_status *status;
1162
1163                if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1164                                buffer_size - 1)) {
1165                        HPI_DEBUG_LOG(ERROR,
1166                                "buffer size must be 2^N not %d\n",
1167                                phm->u.d.u.buffer.buffer_size);
1168                        phr->error = HPI_ERROR_INVALID_DATASIZE;
1169                        return;
1170                }
1171
1172                phw->instream_host_buffer_size[phm->obj_index] =
1173                        phm->u.d.u.buffer.buffer_size;
1174                status = &interface->instream_host_buffer_status[phm->
1175                        obj_index];
1176                status->samples_processed = 0;
1177                status->stream_state = HPI_STATE_STOPPED;
1178                status->dSP_index = 0;
1179                status->host_index = status->dSP_index;
1180                status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1181
1182                hw_message(pao, phm, phr);
1183                if (phr->error
1184                        && hpios_locked_mem_valid(&phw->
1185                                instream_host_buffers[phm->obj_index])) {
1186                        hpios_locked_mem_free(&phw->instream_host_buffers
1187                                [phm->obj_index]);
1188                        phw->instream_host_buffer_size[phm->obj_index] = 0;
1189                }
1190        }
1191}
1192
1193static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
1194        struct hpi_message *phm, struct hpi_response *phr)
1195{
1196        struct hpi_hw_obj *phw = pao->priv;
1197        struct bus_master_interface *interface = phw->p_interface_buffer;
1198        struct hpi_hostbuffer_status *status;
1199        u8 *p_bbm_data;
1200
1201        if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1202                                obj_index])) {
1203                if (hpios_locked_mem_get_virt_addr(&phw->
1204                                instream_host_buffers[phm->obj_index],
1205                                (void *)&p_bbm_data)) {
1206                        phr->error = HPI_ERROR_INVALID_OPERATION;
1207                        return;
1208                }
1209                status = &interface->instream_host_buffer_status[phm->
1210                        obj_index];
1211                hpi_init_response(phr, HPI_OBJ_ISTREAM,
1212                        HPI_ISTREAM_HOSTBUFFER_GET_INFO, 0);
1213                phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
1214                phr->u.d.u.hostbuffer_info.p_status = status;
1215        } else {
1216                hpi_init_response(phr, HPI_OBJ_ISTREAM,
1217                        HPI_ISTREAM_HOSTBUFFER_GET_INFO,
1218                        HPI_ERROR_INVALID_OPERATION);
1219        }
1220}
1221
1222static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
1223        struct hpi_message *phm, struct hpi_response *phr)
1224{
1225        struct hpi_hw_obj *phw = pao->priv;
1226        u32 command = phm->u.d.u.buffer.command;
1227
1228        if (phw->instream_host_buffer_size[phm->obj_index]) {
1229                if (command == HPI_BUFFER_CMD_EXTERNAL
1230                        || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
1231                        phw->instream_host_buffer_size[phm->obj_index] = 0;
1232                        hw_message(pao, phm, phr);
1233                }
1234
1235                if (command == HPI_BUFFER_CMD_EXTERNAL
1236                        || command == HPI_BUFFER_CMD_INTERNAL_FREE)
1237                        hpios_locked_mem_free(&phw->instream_host_buffers
1238                                [phm->obj_index]);
1239
1240        } else {
1241                /* Should HPI_ERROR_INVALID_OPERATION be returned
1242                   if no host buffer is allocated? */
1243                hpi_init_response(phr, HPI_OBJ_ISTREAM,
1244                        HPI_ISTREAM_HOSTBUFFER_FREE, 0);
1245
1246        }
1247
1248}
1249
1250static void instream_start(struct hpi_adapter_obj *pao,
1251        struct hpi_message *phm, struct hpi_response *phr)
1252{
1253        hw_message(pao, phm, phr);
1254}
1255
1256static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status)
1257{
1258        return status->dSP_index - status->host_index;
1259}
1260
1261static void instream_read(struct hpi_adapter_obj *pao,
1262        struct hpi_message *phm, struct hpi_response *phr)
1263{
1264        struct hpi_hw_obj *phw = pao->priv;
1265        struct bus_master_interface *interface = phw->p_interface_buffer;
1266        struct hpi_hostbuffer_status *status;
1267        u32 data_available;
1268        u8 *p_bbm_data;
1269        u32 l_first_read;
1270        u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1271
1272        if (!phw->instream_host_buffer_size[phm->obj_index]) {
1273                hw_message(pao, phm, phr);
1274                return;
1275        }
1276        hpi_init_response(phr, phm->object, phm->function, 0);
1277
1278        status = &interface->instream_host_buffer_status[phm->obj_index];
1279        data_available = instream_get_bytes_available(status);
1280        if (data_available < phm->u.d.u.data.data_size) {
1281                phr->error = HPI_ERROR_INVALID_DATASIZE;
1282                return;
1283        }
1284
1285        if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1286                                obj_index])) {
1287                if (hpios_locked_mem_get_virt_addr(&phw->
1288                                instream_host_buffers[phm->obj_index],
1289                                (void *)&p_bbm_data)) {
1290                        phr->error = HPI_ERROR_INVALID_OPERATION;
1291                        return;
1292                }
1293
1294                /* either all data,
1295                   or enough to fit from current to end of BBM buffer */
1296                l_first_read =
1297                        min(phm->u.d.u.data.data_size,
1298                        status->size_in_bytes -
1299                        (status->host_index & (status->size_in_bytes - 1)));
1300
1301                memcpy(p_app_data,
1302                        p_bbm_data +
1303                        (status->host_index & (status->size_in_bytes - 1)),
1304                        l_first_read);
1305                /* remaining data if any */
1306                memcpy(p_app_data + l_first_read, p_bbm_data,
1307                        phm->u.d.u.data.data_size - l_first_read);
1308        }
1309        status->host_index += phm->u.d.u.data.data_size;
1310}
1311
1312static void instream_get_info(struct hpi_adapter_obj *pao,
1313        struct hpi_message *phm, struct hpi_response *phr)
1314{
1315        struct hpi_hw_obj *phw = pao->priv;
1316        struct bus_master_interface *interface = phw->p_interface_buffer;
1317        struct hpi_hostbuffer_status *status;
1318        if (!phw->instream_host_buffer_size[phm->obj_index]) {
1319                hw_message(pao, phm, phr);
1320                return;
1321        }
1322
1323        status = &interface->instream_host_buffer_status[phm->obj_index];
1324
1325        hpi_init_response(phr, phm->object, phm->function, 0);
1326
1327        phr->u.d.u.stream_info.state = (u16)status->stream_state;
1328        phr->u.d.u.stream_info.samples_transferred =
1329                status->samples_processed;
1330        phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1331        phr->u.d.u.stream_info.data_available =
1332                instream_get_bytes_available(status);
1333        phr->u.d.u.stream_info.auxiliary_data_available =
1334                status->auxiliary_data_available;
1335}
1336
1337/*****************************************************************************/
1338/* LOW-LEVEL */
1339#define HPI6205_MAX_FILES_TO_LOAD 2
1340
1341static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1342        u32 *pos_error_code)
1343{
1344        struct hpi_hw_obj *phw = pao->priv;
1345        struct dsp_code dsp_code;
1346        u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1347        u16 firmware_id = pao->pci.subsys_device_id;
1348        u32 temp;
1349        int dsp = 0, i = 0;
1350        u16 err = 0;
1351
1352        boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1353
1354        /* special cases where firmware_id != subsys ID */
1355        switch (firmware_id) {
1356        case HPI_ADAPTER_FAMILY_ASI(0x5000):
1357                boot_code_id[0] = firmware_id;
1358                firmware_id = 0;
1359                break;
1360        case HPI_ADAPTER_FAMILY_ASI(0x5300):
1361        case HPI_ADAPTER_FAMILY_ASI(0x5400):
1362        case HPI_ADAPTER_FAMILY_ASI(0x6300):
1363                firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400);
1364                break;
1365        case HPI_ADAPTER_FAMILY_ASI(0x5600):
1366        case HPI_ADAPTER_FAMILY_ASI(0x6500):
1367                firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600);
1368                break;
1369        case HPI_ADAPTER_FAMILY_ASI(0x8800):
1370                firmware_id = HPI_ADAPTER_FAMILY_ASI(0x8900);
1371                break;
1372        }
1373        boot_code_id[1] = firmware_id;
1374
1375        /* reset DSP by writing a 1 to the WARMRESET bit */
1376        temp = C6205_HDCR_WARMRESET;
1377        iowrite32(temp, phw->prHDCR);
1378        hpios_delay_micro_seconds(1000);
1379
1380        /* check that PCI i/f was configured by EEPROM */
1381        temp = ioread32(phw->prHSR);
1382        if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1383                C6205_HSR_EEREAD)
1384                return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM);
1385        temp |= 0x04;
1386        /* disable PINTA interrupt */
1387        iowrite32(temp, phw->prHSR);
1388
1389        /* check control register reports PCI boot mode */
1390        temp = ioread32(phw->prHDCR);
1391        if (!(temp & C6205_HDCR_PCIBOOT))
1392                return hpi6205_error(0, HPI6205_ERROR_6205_REG);
1393
1394        /* try writing a couple of numbers to the DSP page register */
1395        /* and reading them back. */
1396        temp = 1;
1397        iowrite32(temp, phw->prDSPP);
1398        if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1399                return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1400        temp = 2;
1401        iowrite32(temp, phw->prDSPP);
1402        if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1403                return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1404        temp = 3;
1405        iowrite32(temp, phw->prDSPP);
1406        if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1407                return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1408        /* reset DSP page to the correct number */
1409        temp = 0;
1410        iowrite32(temp, phw->prDSPP);
1411        if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1412                return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1413        phw->dsp_page = 0;
1414
1415        /* release 6713 from reset before 6205 is bootloaded.
1416           This ensures that the EMIF is inactive,
1417           and the 6713 HPI gets the correct bootmode etc
1418         */
1419        if (boot_code_id[1] != 0) {
1420                /* DSP 1 is a C6713 */
1421                /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1422                boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202);
1423                hpios_delay_micro_seconds(100);
1424                /* Reset the 6713 #1 - revB */
1425                boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
1426
1427                /* dummy read every 4 words for 6205 advisory 1.4.4 */
1428                boot_loader_read_mem32(pao, 0, 0);
1429
1430                hpios_delay_micro_seconds(100);
1431                /* Release C6713 from reset - revB */
1432                boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4);
1433                hpios_delay_micro_seconds(100);
1434        }
1435
1436        for (dsp = 0; dsp < HPI6205_MAX_FILES_TO_LOAD; dsp++) {
1437                /* is there a DSP to load? */
1438                if (boot_code_id[dsp] == 0)
1439                        continue;
1440
1441                err = boot_loader_config_emif(pao, dsp);
1442                if (err)
1443                        return err;
1444
1445                err = boot_loader_test_internal_memory(pao, dsp);
1446                if (err)
1447                        return err;
1448
1449                err = boot_loader_test_external_memory(pao, dsp);
1450                if (err)
1451                        return err;
1452
1453                err = boot_loader_test_pld(pao, dsp);
1454                if (err)
1455                        return err;
1456
1457                /* write the DSP code down into the DSPs memory */
1458                dsp_code.ps_dev = pao->pci.p_os_data;
1459                err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1460                        pos_error_code);
1461                if (err)
1462                        return err;
1463
1464                while (1) {
1465                        u32 length;
1466                        u32 address;
1467                        u32 type;
1468                        u32 *pcode;
1469
1470                        err = hpi_dsp_code_read_word(&dsp_code, &length);
1471                        if (err)
1472                                break;
1473                        if (length == 0xFFFFFFFF)
1474                                break;  /* end of code */
1475
1476                        err = hpi_dsp_code_read_word(&dsp_code, &address);
1477                        if (err)
1478                                break;
1479                        err = hpi_dsp_code_read_word(&dsp_code, &type);
1480                        if (err)
1481                                break;
1482                        err = hpi_dsp_code_read_block(length, &dsp_code,
1483                                &pcode);
1484                        if (err)
1485                                break;
1486                        for (i = 0; i < (int)length; i++) {
1487                                err = boot_loader_write_mem32(pao, dsp,
1488                                        address, *pcode);
1489                                if (err)
1490                                        break;
1491                                /* dummy read every 4 words */
1492                                /* for 6205 advisory 1.4.4 */
1493                                if (i % 4 == 0)
1494                                        boot_loader_read_mem32(pao, dsp,
1495                                                address);
1496                                pcode++;
1497                                address += 4;
1498                        }
1499
1500                }
1501                if (err) {
1502                        hpi_dsp_code_close(&dsp_code);
1503                        return err;
1504                }
1505
1506                /* verify code */
1507                hpi_dsp_code_rewind(&dsp_code);
1508                while (1) {
1509                        u32 length = 0;
1510                        u32 address = 0;
1511                        u32 type = 0;
1512                        u32 *pcode = NULL;
1513                        u32 data = 0;
1514
1515                        hpi_dsp_code_read_word(&dsp_code, &length);
1516                        if (length == 0xFFFFFFFF)
1517                                break;  /* end of code */
1518
1519                        hpi_dsp_code_read_word(&dsp_code, &address);
1520                        hpi_dsp_code_read_word(&dsp_code, &type);
1521                        hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1522
1523                        for (i = 0; i < (int)length; i++) {
1524                                data = boot_loader_read_mem32(pao, dsp,
1525                                        address);
1526                                if (data != *pcode) {
1527                                        err = 0;
1528                                        break;
1529                                }
1530                                pcode++;
1531                                address += 4;
1532                        }
1533                        if (err)
1534                                break;
1535                }
1536                hpi_dsp_code_close(&dsp_code);
1537                if (err)
1538                        return err;
1539        }
1540
1541        /* After bootloading all DSPs, start DSP0 running
1542         * The DSP0 code will handle starting and synchronizing with its slaves
1543         */
1544        if (phw->p_interface_buffer) {
1545                /* we need to tell the card the physical PCI address */
1546                u32 physicalPC_iaddress;
1547                struct bus_master_interface *interface =
1548                        phw->p_interface_buffer;
1549                u32 host_mailbox_address_on_dsp;
1550                u32 physicalPC_iaddress_verify = 0;
1551                int time_out = 10;
1552                /* set ack so we know when DSP is ready to go */
1553                /* (dwDspAck will be changed to HIF_RESET) */
1554                interface->dsp_ack = H620_HIF_UNKNOWN;
1555                wmb();  /* ensure ack is written before dsp writes back */
1556
1557                err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
1558                        &physicalPC_iaddress);
1559
1560                /* locate the host mailbox on the DSP. */
1561                host_mailbox_address_on_dsp = 0x80000000;
1562                while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1563                        && time_out--) {
1564                        err = boot_loader_write_mem32(pao, 0,
1565                                host_mailbox_address_on_dsp,
1566                                physicalPC_iaddress);
1567                        physicalPC_iaddress_verify =
1568                                boot_loader_read_mem32(pao, 0,
1569                                host_mailbox_address_on_dsp);
1570                }
1571        }
1572        HPI_DEBUG_LOG(DEBUG, "starting DS_ps running\n");
1573        /* enable interrupts */
1574        temp = ioread32(phw->prHSR);
1575        temp &= ~(u32)C6205_HSR_INTAM;
1576        iowrite32(temp, phw->prHSR);
1577
1578        /* start code running... */
1579        temp = ioread32(phw->prHDCR);
1580        temp |= (u32)C6205_HDCR_DSPINT;
1581        iowrite32(temp, phw->prHDCR);
1582
1583        /* give the DSP 10ms to start up */
1584        hpios_delay_micro_seconds(10000);
1585        return err;
1586
1587}
1588
1589/*****************************************************************************/
1590/* Bootloader utility functions */
1591
1592static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1593        u32 address)
1594{
1595        struct hpi_hw_obj *phw = pao->priv;
1596        u32 data = 0;
1597        __iomem u32 *p_data;
1598
1599        if (dsp_index == 0) {
1600                /* DSP 0 is always C6205 */
1601                if ((address >= 0x01800000) & (address < 0x02000000)) {
1602                        /* BAR1 register access */
1603                        p_data = pao->pci.ap_mem_base[1] +
1604                                (address & 0x007fffff) /
1605                                sizeof(*pao->pci.ap_mem_base[1]);
1606                        /* HPI_DEBUG_LOG(WARNING,
1607                           "BAR1 access %08x\n", dwAddress); */
1608                } else {
1609                        u32 dw4M_page = address >> 22L;
1610                        if (dw4M_page != phw->dsp_page) {
1611                                phw->dsp_page = dw4M_page;
1612                                /* *INDENT OFF* */
1613                                iowrite32(phw->dsp_page, phw->prDSPP);
1614                                /* *INDENT-ON* */
1615                        }
1616                        address &= 0x3fffff;    /* address within 4M page */
1617                        /* BAR0 memory access */
1618                        p_data = pao->pci.ap_mem_base[0] +
1619                                address / sizeof(u32);
1620                }
1621                data = ioread32(p_data);
1622        } else if (dsp_index == 1) {
1623                /* DSP 1 is a C6713 */
1624                u32 lsb;
1625                boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1626                boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1627                lsb = boot_loader_read_mem32(pao, 0, HPIDL_ADDR);
1628                data = boot_loader_read_mem32(pao, 0, HPIDH_ADDR);
1629                data = (data << 16) | (lsb & 0xFFFF);
1630        }
1631        return data;
1632}
1633
1634static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1635        u32 address, u32 data)
1636{
1637        struct hpi_hw_obj *phw = pao->priv;
1638        u16 err = 0;
1639        __iomem u32 *p_data;
1640        /*      u32 dwVerifyData=0; */
1641
1642        if (dsp_index == 0) {
1643                /* DSP 0 is always C6205 */
1644                if ((address >= 0x01800000) & (address < 0x02000000)) {
1645                        /* BAR1 - DSP  register access using */
1646                        /* Non-prefetchable PCI access */
1647                        p_data = pao->pci.ap_mem_base[1] +
1648                                (address & 0x007fffff) /
1649                                sizeof(*pao->pci.ap_mem_base[1]);
1650                } else {
1651                        /* BAR0 access - all of DSP memory using */
1652                        /* pre-fetchable PCI access */
1653                        u32 dw4M_page = address >> 22L;
1654                        if (dw4M_page != phw->dsp_page) {
1655                                phw->dsp_page = dw4M_page;
1656                                /* *INDENT-OFF* */
1657                                iowrite32(phw->dsp_page, phw->prDSPP);
1658                                /* *INDENT-ON* */
1659                        }
1660                        address &= 0x3fffff;    /* address within 4M page */
1661                        p_data = pao->pci.ap_mem_base[0] +
1662                                address / sizeof(u32);
1663                }
1664                iowrite32(data, p_data);
1665        } else if (dsp_index == 1) {
1666                /* DSP 1 is a C6713 */
1667                boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1668                boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1669
1670                /* dummy read every 4 words for 6205 advisory 1.4.4 */
1671                boot_loader_read_mem32(pao, 0, 0);
1672
1673                boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
1674                boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
1675
1676                /* dummy read every 4 words for 6205 advisory 1.4.4 */
1677                boot_loader_read_mem32(pao, 0, 0);
1678        } else
1679                err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1680        return err;
1681}
1682
1683static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1684{
1685        u16 err = 0;
1686
1687        if (dsp_index == 0) {
1688                u32 setting;
1689
1690                /* DSP 0 is always C6205 */
1691
1692                /* Set the EMIF */
1693                /* memory map of C6205 */
1694                /* 00000000-0000FFFF    16Kx32 internal program */
1695                /* 00400000-00BFFFFF    CE0     2Mx32 SDRAM running @ 100MHz */
1696
1697                /* EMIF config */
1698                /*------------ */
1699                /* Global EMIF control */
1700                boot_loader_write_mem32(pao, dsp_index, 0x01800000, 0x3779);
1701#define WS_OFS 28
1702#define WST_OFS 22
1703#define WH_OFS 20
1704#define RS_OFS 16
1705#define RST_OFS 8
1706#define MTYPE_OFS 4
1707#define RH_OFS 0
1708
1709                /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1710                setting = 0x00000030;
1711                boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1712                if (setting != boot_loader_read_mem32(pao, dsp_index,
1713                                0x01800008))
1714                        return hpi6205_error(dsp_index,
1715                                HPI6205_ERROR_DSP_EMIF);
1716
1717                /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1718                /* which occupies D15..0. 6713 starts at 27MHz, so need */
1719                /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1720                /* WST should be 71, but 63  is max possible */
1721                setting =
1722                        (1L << WS_OFS) | (63L << WST_OFS) | (1L << WH_OFS) |
1723                        (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1724                        (2L << MTYPE_OFS);
1725                boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1726                if (setting != boot_loader_read_mem32(pao, dsp_index,
1727                                0x01800004))
1728                        return hpi6205_error(dsp_index,
1729                                HPI6205_ERROR_DSP_EMIF);
1730
1731                /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1732                /* which occupies D15..0. 6713 starts at 27MHz, so need */
1733                /* plenty of wait states */
1734                setting =
1735                        (1L << WS_OFS) | (28L << WST_OFS) | (1L << WH_OFS) |
1736                        (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1737                        (2L << MTYPE_OFS);
1738                boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1739                if (setting != boot_loader_read_mem32(pao, dsp_index,
1740                                0x01800010))
1741                        return hpi6205_error(dsp_index,
1742                                HPI6205_ERROR_DSP_EMIF);
1743
1744                /* EMIF CE3 setup - 32 bit async. */
1745                /* This is the PLD on the ASI5000 cards only */
1746                setting =
1747                        (1L << WS_OFS) | (10L << WST_OFS) | (1L << WH_OFS) |
1748                        (1L << RS_OFS) | (10L << RST_OFS) | (1L << RH_OFS) |
1749                        (2L << MTYPE_OFS);
1750                boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1751                if (setting != boot_loader_read_mem32(pao, dsp_index,
1752                                0x01800014))
1753                        return hpi6205_error(dsp_index,
1754                                HPI6205_ERROR_DSP_EMIF);
1755
1756                /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1757                /*  need to use this else DSP code crashes? */
1758                boot_loader_write_mem32(pao, dsp_index, 0x01800018,
1759                        0x07117000);
1760
1761                /* EMIF SDRAM Refresh Timing */
1762                /* EMIF SDRAM timing  (orig = 0x410, emulator = 0x61a) */
1763                boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
1764                        0x00000410);
1765
1766        } else if (dsp_index == 1) {
1767                /* test access to the C6713s HPI registers */
1768                u32 write_data = 0, read_data = 0, i = 0;
1769
1770                /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1771                write_data = 1;
1772                boot_loader_write_mem32(pao, 0, HPICL_ADDR, write_data);
1773                boot_loader_write_mem32(pao, 0, HPICH_ADDR, write_data);
1774                /* C67 HPI is on lower 16bits of 32bit EMIF */
1775                read_data =
1776                        0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1777                if (write_data != read_data) {
1778                        err = hpi6205_error(dsp_index,
1779                                HPI6205_ERROR_C6713_HPIC);
1780                        HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
1781                                read_data);
1782
1783                        return err;
1784                }
1785                /* HPIA - walking ones test */
1786                write_data = 1;
1787                for (i = 0; i < 32; i++) {
1788                        boot_loader_write_mem32(pao, 0, HPIAL_ADDR,
1789                                write_data);
1790                        boot_loader_write_mem32(pao, 0, HPIAH_ADDR,
1791                                (write_data >> 16));
1792                        read_data =
1793                                0xFFFF & boot_loader_read_mem32(pao, 0,
1794                                HPIAL_ADDR);
1795                        read_data =
1796                                read_data | ((0xFFFF &
1797                                        boot_loader_read_mem32(pao, 0,
1798                                                HPIAH_ADDR))
1799                                << 16);
1800                        if (read_data != write_data) {
1801                                err = hpi6205_error(dsp_index,
1802                                        HPI6205_ERROR_C6713_HPIA);
1803                                HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
1804                                        write_data, read_data);
1805                                return err;
1806                        }
1807                        write_data = write_data << 1;
1808                }
1809
1810                /* setup C67x PLL
1811                 *  ** C6713 datasheet says we cannot program PLL from HPI,
1812                 * and indeed if we try to set the PLL multiply from the HPI,
1813                 * the PLL does not seem to lock, so we enable the PLL and
1814                 * use the default multiply of x 7, which for a 27MHz clock
1815                 * gives a DSP speed of 189MHz
1816                 */
1817                /* bypass PLL */
1818                boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0000);
1819                hpios_delay_micro_seconds(1000);
1820                /* EMIF = 189/3=63MHz */
1821                boot_loader_write_mem32(pao, dsp_index, 0x01B7C120, 0x8002);
1822                /* peri = 189/2 */
1823                boot_loader_write_mem32(pao, dsp_index, 0x01B7C11C, 0x8001);
1824                /* cpu  = 189/1 */
1825                boot_loader_write_mem32(pao, dsp_index, 0x01B7C118, 0x8000);
1826                hpios_delay_micro_seconds(1000);
1827                /* ** SGT test to take GPO3 high when we start the PLL */
1828                /* and low when the delay is completed */
1829                /* FSX0 <- '1' (GPO3) */
1830                boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A0A);
1831                /* PLL not bypassed */
1832                boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0001);
1833                hpios_delay_micro_seconds(1000);
1834                /* FSX0 <- '0' (GPO3) */
1835                boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A02);
1836
1837                /* 6205 EMIF CE1 resetup - 32 bit async. */
1838                /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1839                boot_loader_write_mem32(pao, 0, 0x01800004,     /* CE1 */
1840                        (1L << WS_OFS) | (8L << WST_OFS) | (1L << WH_OFS) |
1841                        (1L << RS_OFS) | (12L << RST_OFS) | (1L << RH_OFS) |
1842                        (2L << MTYPE_OFS));
1843
1844                hpios_delay_micro_seconds(1000);
1845
1846                /* check that we can read one of the PLL registers */
1847                /* PLL should not be bypassed! */
1848                if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1849                        != 0x0001) {
1850                        err = hpi6205_error(dsp_index,
1851                                HPI6205_ERROR_C6713_PLL);
1852                        return err;
1853                }
1854                /* setup C67x EMIF  (note this is the only use of
1855                   BAR1 via BootLoader_WriteMem32) */
1856                boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1857                        0x000034A8);
1858                boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1859                        0x00000030);
1860                boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1861                        0x001BDF29);
1862                boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1863                        0x47117000);
1864                boot_loader_write_mem32(pao, dsp_index,
1865                        C6713_EMIF_SDRAMTIMING, 0x00000410);
1866
1867                hpios_delay_micro_seconds(1000);
1868        } else if (dsp_index == 2) {
1869                /* DSP 2 is a C6713 */
1870
1871        } else
1872                err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1873        return err;
1874}
1875
1876static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1877        u32 start_address, u32 length)
1878{
1879        u32 i = 0, j = 0;
1880        u32 test_addr = 0;
1881        u32 test_data = 0, data = 0;
1882
1883        length = 1000;
1884
1885        /* for 1st word, test each bit in the 32bit word, */
1886        /* dwLength specifies number of 32bit words to test */
1887        /*for(i=0; i<dwLength; i++) */
1888        i = 0;
1889        {
1890                test_addr = start_address + i * 4;
1891                test_data = 0x00000001;
1892                for (j = 0; j < 32; j++) {
1893                        boot_loader_write_mem32(pao, dsp_index, test_addr,
1894                                test_data);
1895                        data = boot_loader_read_mem32(pao, dsp_index,
1896                                test_addr);
1897                        if (data != test_data) {
1898                                HPI_DEBUG_LOG(VERBOSE,
1899                                        "memtest error details  "
1900                                        "%08x %08x %08x %i\n", test_addr,
1901                                        test_data, data, dsp_index);
1902                                return 1;       /* error */
1903                        }
1904                        test_data = test_data << 1;
1905                }       /* for(j) */
1906        }       /* for(i) */
1907
1908        /* for the next 100 locations test each location, leaving it as zero */
1909        /* write a zero to the next word in memory before we read */
1910        /* the previous write to make sure every memory location is unique */
1911        for (i = 0; i < 100; i++) {
1912                test_addr = start_address + i * 4;
1913                test_data = 0xA5A55A5A;
1914                boot_loader_write_mem32(pao, dsp_index, test_addr, test_data);
1915                boot_loader_write_mem32(pao, dsp_index, test_addr + 4, 0);
1916                data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1917                if (data != test_data) {
1918                        HPI_DEBUG_LOG(VERBOSE,
1919                                "memtest error details  "
1920                                "%08x %08x %08x %i\n", test_addr, test_data,
1921                                data, dsp_index);
1922                        return 1;       /* error */
1923                }
1924                /* leave location as zero */
1925                boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1926        }
1927
1928        /* zero out entire memory block */
1929        for (i = 0; i < length; i++) {
1930                test_addr = start_address + i * 4;
1931                boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1932        }
1933        return 0;
1934}
1935
1936static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1937        int dsp_index)
1938{
1939        int err = 0;
1940        if (dsp_index == 0) {
1941                /* DSP 0 is a C6205 */
1942                /* 64K prog mem */
1943                err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1944                        0x10000);
1945                if (!err)
1946                        /* 64K data mem */
1947                        err = boot_loader_test_memory(pao, dsp_index,
1948                                0x80000000, 0x10000);
1949        } else if ((dsp_index == 1) || (dsp_index == 2)) {
1950                /* DSP 1&2 are a C6713 */
1951                /* 192K internal mem */
1952                err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1953                        0x30000);
1954                if (!err)
1955                        /* 64K internal mem / L2 cache */
1956                        err = boot_loader_test_memory(pao, dsp_index,
1957                                0x00030000, 0x10000);
1958        } else
1959                return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1960
1961        if (err)
1962                return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
1963        else
1964                return 0;
1965}
1966
1967static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1968        int dsp_index)
1969{
1970        u32 dRAM_start_address = 0;
1971        u32 dRAM_size = 0;
1972
1973        if (dsp_index == 0) {
1974                /* only test for SDRAM if an ASI5000 card */
1975                if (pao->pci.subsys_device_id == 0x5000) {
1976                        /* DSP 0 is always C6205 */
1977                        dRAM_start_address = 0x00400000;
1978                        dRAM_size = 0x200000;
1979                        /*dwDRAMinc=1024; */
1980                } else
1981                        return 0;
1982        } else if ((dsp_index == 1) || (dsp_index == 2)) {
1983                /* DSP 1 is a C6713 */
1984                dRAM_start_address = 0x80000000;
1985                dRAM_size = 0x200000;
1986                /*dwDRAMinc=1024; */
1987        } else
1988                return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1989
1990        if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1991                        dRAM_size))
1992                return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM);
1993        return 0;
1994}
1995
1996static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1997{
1998        u32 data = 0;
1999        if (dsp_index == 0) {
2000                /* only test for DSP0 PLD on ASI5000 card */
2001                if (pao->pci.subsys_device_id == 0x5000) {
2002                        /* PLD is located at CE3=0x03000000 */
2003                        data = boot_loader_read_mem32(pao, dsp_index,
2004                                0x03000008);
2005                        if ((data & 0xF) != 0x5)
2006                                return hpi6205_error(dsp_index,
2007                                        HPI6205_ERROR_DSP_PLD);
2008                        data = boot_loader_read_mem32(pao, dsp_index,
2009                                0x0300000C);
2010                        if ((data & 0xF) != 0xA)
2011                                return hpi6205_error(dsp_index,
2012                                        HPI6205_ERROR_DSP_PLD);
2013                }
2014        } else if (dsp_index == 1) {
2015                /* DSP 1 is a C6713 */
2016                if (pao->pci.subsys_device_id == 0x8700) {
2017                        /* PLD is located at CE1=0x90000000 */
2018                        data = boot_loader_read_mem32(pao, dsp_index,
2019                                0x90000010);
2020                        if ((data & 0xFF) != 0xAA)
2021                                return hpi6205_error(dsp_index,
2022                                        HPI6205_ERROR_DSP_PLD);
2023                        /* 8713 - LED on */
2024                        boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2025                                0x02);
2026                }
2027        }
2028        return 0;
2029}
2030
2031/** Transfer data to or from DSP
2032 nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2033*/
2034static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2035        u32 data_size, int operation)
2036{
2037        struct hpi_hw_obj *phw = pao->priv;
2038        u32 data_transferred = 0;
2039        u16 err = 0;
2040#ifndef HPI6205_NO_HSR_POLL
2041        u32 time_out;
2042#endif
2043        u32 temp2;
2044        struct bus_master_interface *interface = phw->p_interface_buffer;
2045
2046        if (!p_data)
2047                return HPI_ERROR_INVALID_DATA_TRANSFER;
2048
2049        data_size &= ~3L;       /* round data_size down to nearest 4 bytes */
2050
2051        /* make sure state is IDLE */
2052        if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
2053                return HPI_ERROR_DSP_HARDWARE;
2054
2055        while (data_transferred < data_size) {
2056                u32 this_copy = data_size - data_transferred;
2057
2058                if (this_copy > HPI6205_SIZEOF_DATA)
2059                        this_copy = HPI6205_SIZEOF_DATA;
2060
2061                if (operation == H620_HIF_SEND_DATA)
2062                        memcpy((void *)&interface->u.b_data[0],
2063                                &p_data[data_transferred], this_copy);
2064
2065                interface->transfer_size_in_bytes = this_copy;
2066
2067#ifdef HPI6205_NO_HSR_POLL
2068                /* DSP must change this back to nOperation */
2069                interface->dsp_ack = H620_HIF_IDLE;
2070#endif
2071
2072                send_dsp_command(phw, operation);
2073
2074#ifdef HPI6205_NO_HSR_POLL
2075                temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2076                HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2077                        HPI6205_TIMEOUT - temp2, this_copy);
2078
2079                if (!temp2) {
2080                        /* timed out */
2081                        HPI_DEBUG_LOG(ERROR,
2082                                "timed out waiting for " "state %d got %d\n",
2083                                operation, interface->dsp_ack);
2084
2085                        break;
2086                }
2087#else
2088                /* spin waiting on the result */
2089                time_out = HPI6205_TIMEOUT;
2090                temp2 = 0;
2091                while ((temp2 == 0) && time_out--) {
2092                        /* give 16k bus mastering transfer time to happen */
2093                        /*(16k / 132Mbytes/s = 122usec) */
2094                        hpios_delay_micro_seconds(20);
2095                        temp2 = ioread32(phw->prHSR);
2096                        temp2 &= C6205_HSR_INTSRC;
2097                }
2098                HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2099                        HPI6205_TIMEOUT - time_out, this_copy);
2100                if (temp2 == C6205_HSR_INTSRC) {
2101                        HPI_DEBUG_LOG(VERBOSE,
2102                                "interrupt from HIF <data> OK\n");
2103                        /*
2104                           if(interface->dwDspAck != nOperation) {
2105                           HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2106                           expected %d \n",
2107                           interface->dwDspAck,nOperation);
2108                           }
2109                         */
2110                }
2111/* need to handle this differently... */
2112                else {
2113                        HPI_DEBUG_LOG(ERROR,
2114                                "interrupt from HIF <data> BAD\n");
2115                        err = HPI_ERROR_DSP_HARDWARE;
2116                }
2117
2118                /* reset the interrupt from the DSP */
2119                iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2120#endif
2121                if (operation == H620_HIF_GET_DATA)
2122                        memcpy(&p_data[data_transferred],
2123                                (void *)&interface->u.b_data[0], this_copy);
2124
2125                data_transferred += this_copy;
2126        }
2127        if (interface->dsp_ack != operation)
2128                HPI_DEBUG_LOG(DEBUG, "interface->dsp_ack=%d, expected %d\n",
2129                        interface->dsp_ack, operation);
2130        /*                      err=HPI_ERROR_DSP_HARDWARE; */
2131
2132        send_dsp_command(phw, H620_HIF_IDLE);
2133
2134        return err;
2135}
2136
2137/* wait for up to timeout_us microseconds for the DSP
2138   to signal state by DMA into dwDspAck
2139*/
2140static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2141{
2142        struct bus_master_interface *interface = phw->p_interface_buffer;
2143        int t = timeout_us / 4;
2144
2145        rmb();  /* ensure interface->dsp_ack is up to date */
2146        while ((interface->dsp_ack != state) && --t) {
2147                hpios_delay_micro_seconds(4);
2148                rmb();  /* DSP changes dsp_ack by DMA */
2149        }
2150
2151        /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2152        return t * 4;
2153}
2154
2155/* set the busmaster interface to cmd, then interrupt the DSP */
2156static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2157{
2158        struct bus_master_interface *interface = phw->p_interface_buffer;
2159
2160        u32 r;
2161
2162        interface->host_cmd = cmd;
2163        wmb();  /* DSP gets state by DMA, make sure it is written to memory */
2164        /* before we interrupt the DSP */
2165        r = ioread32(phw->prHDCR);
2166        r |= (u32)C6205_HDCR_DSPINT;
2167        iowrite32(r, phw->prHDCR);
2168        r &= ~(u32)C6205_HDCR_DSPINT;
2169        iowrite32(r, phw->prHDCR);
2170}
2171
2172static unsigned int message_count;
2173
2174static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2175        struct hpi_message *phm, struct hpi_response *phr)
2176{
2177#ifndef HPI6205_NO_HSR_POLL
2178        u32 temp2;
2179#endif
2180        u32 time_out, time_out2;
2181        struct hpi_hw_obj *phw = pao->priv;
2182        struct bus_master_interface *interface = phw->p_interface_buffer;
2183        u16 err = 0;
2184
2185        message_count++;
2186        /* Assume buffer of type struct bus_master_interface
2187           is allocated "noncacheable" */
2188
2189        if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2190                HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2191                return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2192        }
2193        interface->u.message_buffer = *phm;
2194        /* signal we want a response */
2195        send_dsp_command(phw, H620_HIF_GET_RESP);
2196
2197        time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2198
2199        if (time_out2 == 0) {
2200                HPI_DEBUG_LOG(ERROR,
2201                        "(%u) timed out waiting for " "GET_RESP state [%x]\n",
2202                        message_count, interface->dsp_ack);
2203        } else {
2204                HPI_DEBUG_LOG(VERBOSE,
2205                        "(%u) transition to GET_RESP after %u\n",
2206                        message_count, HPI6205_TIMEOUT - time_out2);
2207        }
2208        /* spin waiting on HIF interrupt flag (end of msg process) */
2209        time_out = HPI6205_TIMEOUT;
2210
2211#ifndef HPI6205_NO_HSR_POLL
2212        temp2 = 0;
2213        while ((temp2 == 0) && --time_out) {
2214                temp2 = ioread32(phw->prHSR);
2215                temp2 &= C6205_HSR_INTSRC;
2216                hpios_delay_micro_seconds(1);
2217        }
2218        if (temp2 == C6205_HSR_INTSRC) {
2219                rmb();  /* ensure we see latest value for dsp_ack */
2220                if ((interface->dsp_ack != H620_HIF_GET_RESP)) {
2221                        HPI_DEBUG_LOG(DEBUG,
2222                                "(%u)interface->dsp_ack(0x%x) != "
2223                                "H620_HIF_GET_RESP, t=%u\n", message_count,
2224                                interface->dsp_ack,
2225                                HPI6205_TIMEOUT - time_out);
2226                } else {
2227                        HPI_DEBUG_LOG(VERBOSE,
2228                                "(%u)int with GET_RESP after %u\n",
2229                                message_count, HPI6205_TIMEOUT - time_out);
2230                }
2231
2232        } else {
2233                /* can we do anything else in response to the error ? */
2234                HPI_DEBUG_LOG(ERROR,
2235                        "interrupt from HIF module BAD (function %x)\n",
2236                        phm->function);
2237        }
2238
2239        /* reset the interrupt from the DSP */
2240        iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2241#endif
2242
2243        /* read the result */
2244        if (time_out != 0)
2245                *phr = interface->u.response_buffer;
2246
2247        /* set interface back to idle */
2248        send_dsp_command(phw, H620_HIF_IDLE);
2249
2250        if ((time_out == 0) || (time_out2 == 0)) {
2251                HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2252                return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
2253        }
2254        /* special case for adapter close - */
2255        /* wait for the DSP to indicate it is idle */
2256        if (phm->function == HPI_ADAPTER_CLOSE) {
2257                if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2258                        HPI_DEBUG_LOG(DEBUG,
2259                                "timeout waiting for idle "
2260                                "(on adapter_close)\n");
2261                        return hpi6205_error(0,
2262                                HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2263                }
2264        }
2265        err = hpi_validate_response(phm, phr);
2266        return err;
2267}
2268
2269static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2270        struct hpi_response *phr)
2271{
2272
2273        u16 err = 0;
2274
2275        hpios_dsplock_lock(pao);
2276
2277        err = message_response_sequence(pao, phm, phr);
2278
2279        /* maybe an error response */
2280        if (err) {
2281                /* something failed in the HPI/DSP interface */
2282                phr->error = err;
2283                pao->dsp_crashed++;
2284
2285                /* just the header of the response is valid */
2286                phr->size = sizeof(struct hpi_response_header);
2287                goto err;
2288        } else
2289                pao->dsp_crashed = 0;
2290
2291        if (phr->error != 0)    /* something failed in the DSP */
2292                goto err;
2293
2294        switch (phm->function) {
2295        case HPI_OSTREAM_WRITE:
2296        case HPI_ISTREAM_ANC_WRITE:
2297                err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2298                        phm->u.d.u.data.data_size, H620_HIF_SEND_DATA);
2299                break;
2300
2301        case HPI_ISTREAM_READ:
2302        case HPI_OSTREAM_ANC_READ:
2303                err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2304                        phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
2305                break;
2306
2307        case HPI_CONTROL_SET_STATE:
2308                if (phm->object == HPI_OBJ_CONTROLEX
2309                        && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
2310                        err = hpi6205_transfer_data(pao,
2311                                phm->u.cx.u.cobranet_bigdata.pb_data,
2312                                phm->u.cx.u.cobranet_bigdata.byte_count,
2313                                H620_HIF_SEND_DATA);
2314                break;
2315
2316        case HPI_CONTROL_GET_STATE:
2317                if (phm->object == HPI_OBJ_CONTROLEX
2318                        && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
2319                        err = hpi6205_transfer_data(pao,
2320                                phm->u.cx.u.cobranet_bigdata.pb_data,
2321                                phr->u.cx.u.cobranet_data.byte_count,
2322                                H620_HIF_GET_DATA);
2323                break;
2324        }
2325        phr->error = err;
2326
2327err:
2328        hpios_dsplock_unlock(pao);
2329
2330        return;
2331}
2332