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