1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <soc/qupv3_config_common.h>
6 #include <console/console.h>
7 #include <soc/qup_se_handlers_common.h>
8 #include <soc/qcom_qup_se.h>
9 #include <soc/addressmap.h>
11 static struct elf_se_hdr
*fw_list
[SE_PROTOCOL_MAX
];
13 void qupv3_se_fw_load_and_init(unsigned int bus
, unsigned int protocol
,
18 const uint8_t *cfg_idx_arr
;
19 const uint32_t *cfg_val_arr
;
20 const uint32_t *fw_val_arr
;
21 struct elf_se_hdr
*hdr
;
22 struct qup_regs
*regs
= qup
[bus
].regs
;
23 static const char * const filename
[] = {
24 [SE_PROTOCOL_SPI
] = "fallback/spi_fw",
25 [SE_PROTOCOL_UART
] = "fallback/uart_fw",
26 [SE_PROTOCOL_I2C
] = "fallback/i2c_fw",
29 if (protocol
>= SE_PROTOCOL_MAX
|| !filename
[protocol
])
30 die("*ERROR* * INVALID PROTOCOL ***\n");
32 if (!fw_list
[protocol
]) {
33 fw_list
[protocol
] = cbfs_map(filename
[protocol
], NULL
);
34 if (!fw_list
[protocol
])
35 die("*ERROR* * cbfs_map failed ***\n");
38 hdr
= fw_list
[protocol
];
39 assert(hdr
->magic
== SEFW_MAGIC_HEADER
)
41 cfg_idx_arr
= (const uint8_t *)hdr
+ hdr
->cfg_idx_offset
;
42 cfg_val_arr
= (const uint32_t *)((uint8_t *)hdr
+ hdr
->cfg_val_offset
);
43 fw_val_arr
= (const uint32_t *)((uint8_t *)hdr
+ hdr
->fw_offset
);
45 /* Unlock SE for FW loading */
46 write32(®s
->se_geni_fw_multilock_protns
, 0x0);
47 write32(®s
->se_geni_fw_multilock_msa
, 0x0);
49 /* First, ensure GENI FW is disabled */
50 write32(®s
->geni_output_ctrl
, 0x0);
51 clrbits_le32(®s
->geni_dfs_if_cfg
, GENI_DFS_IF_CFG_DFS_IF_EN_BMSK
);
52 setbits_le32(®s
->geni_cgc_ctrl
, GENI_CGC_CTRL_PROG_RAM_SCLK_OFF_BMSK
53 | GENI_CGC_CTRL_PROG_RAM_HCLK_OFF_BMSK
);
54 write32(®s
->se_geni_clk_ctrl
, 0x0);
55 clrbits_le32(®s
->geni_cgc_ctrl
, GENI_CGC_CTRL_PROG_RAM_SCLK_OFF_BMSK
56 | GENI_CGC_CTRL_PROG_RAM_HCLK_OFF_BMSK
);
59 /* HPG section 3.1.7.1 */
60 if (protocol
!= SE_PROTOCOL_UART
) {
61 setbits_le32(®s
->geni_dfs_if_cfg
,
62 GENI_DFS_IF_CFG_DFS_IF_EN_BMSK
);
63 /* configure clock dfsr */
64 clock_configure_dfsr(bus
);
67 /* HPG section 3.1.7.2 */
68 /* No Init Required */
70 /* HPG section 3.1.7.3 */
71 write32(®s
->dma_general_cfg
,
72 DMA_GENERAL_CFG_AHB_SEC_SLV_CLK_CGC_ON_BMSK
|
73 DMA_GENERAL_CFG_DMA_AHB_SLV_CLK_CGC_ON_BMSK
|
74 DMA_GENERAL_CFG_DMA_TX_CLK_CGC_ON_BMSK
|
75 DMA_GENERAL_CFG_DMA_RX_CLK_CGC_ON_BMSK
);
76 write32(®s
->geni_cgc_ctrl
, DEFAULT_CGC_EN
);
78 /* HPG section 3.1.7.4 */
79 write32(®s
->geni_init_cfg_revision
, hdr
->cfg_version
);
80 write32(®s
->geni_s_init_cfg_revision
, hdr
->cfg_version
);
82 assert(cfg_idx_arr
[hdr
->cfg_size_in_items
- 1] * sizeof(uint32_t) <=
85 for (i
= 0; i
< hdr
->cfg_size_in_items
; i
++)
86 write32(®s
->geni_cfg_reg0
+ cfg_idx_arr
[i
],
89 /* HPG section 3.1.7.9 */
90 /* non-UART configuration, UART driver can configure as desired for UART
92 write32(®s
->geni_rx_rfr_watermark_reg
, FIFO_DEPTH
- 2);
94 /* HPG section 3.1.7.5 */
95 /* Don't change any SPI polarity, client driver will handle this */
96 setbits_le32(®s
->geni_output_ctrl
, DEFAULT_IO_OUTPUT_CTRL_MSK
);
98 /* HPG section 3.1.7.6 */
99 reg_value
= read32(®s
->geni_dma_mode_en
);
101 reg_value
|= GENI_DMA_MODE_EN_GENI_DMA_MODE_EN_BMSK
;
102 write32(®s
->geni_dma_mode_en
, reg_value
);
103 write32(®s
->se_irq_en
, 0x0);
104 write32(®s
->se_gsi_event_en
, SE_GSI_EVENT_EN_BMSK
);
105 } else if (mode
== FIFO
) {
106 reg_value
&= ~GENI_DMA_MODE_EN_GENI_DMA_MODE_EN_BMSK
;
107 write32(®s
->geni_dma_mode_en
, reg_value
);
108 write32(®s
->se_irq_en
, SE_IRQ_EN_RMSK
);
109 write32(®s
->se_gsi_event_en
, 0x0);
110 } else if (mode
== CPU_DMA
) {
111 reg_value
|= GENI_DMA_MODE_EN_GENI_DMA_MODE_EN_BMSK
;
112 write32(®s
->geni_dma_mode_en
, reg_value
);
113 write32(®s
->se_irq_en
, SE_IRQ_EN_RMSK
);
114 write32(®s
->se_gsi_event_en
, 0x0);
117 /* HPG section 3.1.7.7 */
118 write32(®s
->geni_m_irq_enable
,
119 M_COMMON_GENI_M_IRQ_EN
);
120 reg_value
= S_CMD_OVERRUN_EN
| S_ILLEGAL_CMD_EN
|
121 S_CMD_CANCEL_EN
| S_CMD_ABORT_EN
|
122 S_GP_IRQ_0_EN
| S_GP_IRQ_1_EN
|
123 S_GP_IRQ_2_EN
| S_GP_IRQ_3_EN
|
124 S_RX_FIFO_WR_ERR_EN
| S_RX_FIFO_RD_ERR_EN
;
125 write32(®s
->geni_s_irq_enable
, reg_value
);
127 /* HPG section 3.1.7.8 */
129 reg_value
= DMA_TX_IRQ_EN_SET_RESET_DONE_EN_SET_BMSK
|
130 DMA_TX_IRQ_EN_SET_SBE_EN_SET_BMSK
|
131 DMA_TX_IRQ_EN_SET_DMA_DONE_EN_SET_BMSK
;
132 write32(®s
->dma_tx_irq_en_set
, reg_value
);
134 reg_value
= DMA_RX_IRQ_EN_SET_FLUSH_DONE_EN_SET_BMSK
|
135 DMA_RX_IRQ_EN_SET_RESET_DONE_EN_SET_BMSK
|
136 DMA_RX_IRQ_EN_SET_SBE_EN_SET_BMSK
|
137 DMA_RX_IRQ_EN_SET_DMA_DONE_EN_SET_BMSK
;
138 write32(®s
->dma_rx_irq_en_set
, reg_value
);
140 /* HPG section 3.1.7.10 */
141 reg_value
= (hdr
->serial_protocol
<< FW_REV_PROTOCOL_SHFT
) |
142 (hdr
->fw_version
& 0xFF <<
143 FW_REV_VERSION_SHFT
);
144 write32(®s
->se_geni_fw_revision
, reg_value
);
147 (hdr
->serial_protocol
<< FW_REV_PROTOCOL_SHFT
) |
148 (hdr
->fw_version
& 0xFF <<
149 FW_REV_VERSION_SHFT
);
150 write32(®s
->se_s_fw_revision
, reg_value
);
152 assert(hdr
->fw_size_in_items
<= SIZE_GENI_FW_RAM
);
154 memcpy((®s
->se_geni_cfg_ramn
), fw_val_arr
,
155 hdr
->fw_size_in_items
* sizeof(uint32_t));
157 /* HPG section 3.1.7.12 */
158 write32(®s
->geni_force_default_reg
, 0x1);
159 setbits_le32(®s
->geni_cgc_ctrl
, GENI_CGC_CTRL_PROG_RAM_SCLK_OFF_BMSK
160 |GENI_CGC_CTRL_PROG_RAM_HCLK_OFF_BMSK
);
161 setbits_le32(®s
->se_geni_clk_ctrl
, GENI_CLK_CTRL_SER_CLK_SEL_BMSK
);
162 clrbits_le32(®s
->geni_cgc_ctrl
,
163 (GENI_CGC_CTRL_PROG_RAM_SCLK_OFF_BMSK
|
164 GENI_CGC_CTRL_PROG_RAM_HCLK_OFF_BMSK
));
166 /* HPG section 3.1.7.13 */
168 setbits_le32(®s
->se_dma_if_en
, DMA_IF_EN_DMA_IF_EN_BMSK
);
170 /* HPG section 3.1.7.14 */
171 reg_value
= read32(®s
->se_fifo_if_disable
);
172 if ((mode
== MIXED
) || (mode
== FIFO
))
173 reg_value
&= ~FIFO_IF_DISABLE
;
175 reg_value
|= FIFO_IF_DISABLE
;
176 write32(®s
->se_fifo_if_disable
, reg_value
);
177 write32(®s
->se_geni_clk_ctrl
, 0x1);
179 /* Lock SE from FW loading */
180 write32(®s
->se_geni_fw_multilock_protns
, 0x1);
181 write32(®s
->se_geni_fw_multilock_msa
, 0x1);
184 void gpi_firmware_load(int addr
)
188 struct gsi_fw_hdr
*gsi_hdr
;
189 struct gsi_fw_iep
*fwIep
;
190 struct gsi_fw_iram
*fwIRam
;
191 struct gsi_regs
*regs
= (struct gsi_regs
*)(uintptr_t)addr
;
192 static const char * const filename
= "fallback/gsi_fw";
194 /* Assign firmware header base */
195 gsi_hdr
= cbfs_map(filename
, NULL
);
197 die("*ERROR* * cbfs_map() failed ***\n");
199 assert(gsi_hdr
->magic
== GSI_FW_MAGIC_HEADER
)
201 /* Assign IEP entry base */
202 fwIep
= (struct gsi_fw_iep
*)(((uint8_t *)gsi_hdr
) +
203 gsi_hdr
->iep_offset
);
204 /* Assign firmware IRAM entry base */
205 fwIRam
= (struct gsi_fw_iram
*)(((uint8_t *)gsi_hdr
) +
208 clrbits_le32(®s
->gsi_cgc_ctrl
, GSI_CGC_CTRL_REGION_2_HW_CGC_EN_BMSK
);
209 write32(®s
->gsi_periph_base_lsb
, 0);
210 write32(®s
->gsi_periph_base_msb
, 0);
213 for (i
= 0; i
< gsi_hdr
->iep_size_in_items
; i
++) {
214 /* Check if offset does not exceed GSI address space size */
215 if (fwIep
[i
].offset
< GSI_REG_BASE_SIZE
)
216 write32((void *)®s
->gsi_cfg
+ fwIep
[i
].offset
,
220 /* Load firmware in IRAM */
221 assert((gsi_hdr
->fw_size_in_items
* 2) < (GSI_INST_RAM_n_MAX_n
+ 1))
223 /* Program Firmware version */
224 write32(®s
->gsi_manager_mcs_code_ver
, fwIRam
->iram_dword0
);
226 memcpy((®s
->gsi_inst_ramn
), (void *)fwIRam
,
227 gsi_hdr
->fw_size_in_items
* GSI_FW_BYTES_PER_LINE
);
228 setbits_le32(®s
->gsi_mcs_cfg
, GSI_MCS_CFG_MCS_ENABLE_BMSK
);
229 setbits_le32(®s
->gsi_cfg
, GSI_CFG_DOUBLE_MCS_CLK_FREQ_BMSK
230 | GSI_CFG_GSI_ENABLE_BMSK
);
232 write32(®s
->gsi_ee_n_scratch_0_addr
, 0x0);
233 write32(®s
->ee_n_gsi_ee_generic_cmd
, 0x81);
236 regVal
= read32(®s
->gsi_ee_n_scratch_0_addr
);
237 } while (regVal
> 1);
240 static void qup_common_init(int addr
)
242 struct qupv3_common_reg
*qupv3_common
;
243 /* HPG section 3.1.2 */
244 qupv3_common
= (struct qupv3_common_reg
*)(uintptr_t)addr
;
245 setbits32(&qupv3_common
->qupv3_common_cfg_reg
,
246 QUPV3_COMMON_CFG_FAST_SWITCH_TO_HIGH_DISABLE_BMSK
);
248 /* HPG section 3.1.7.3 */
249 setbits32(&qupv3_common
->qupv3_se_ahb_m_cfg_reg
,
250 QUPV3_SE_AHB_M_CFG_AHB_M_CLK_CGC_ON_BMSK
);
253 void qupv3_fw_init(void)
257 /* Turn on all QUP clocks */
258 for (i
= 0; i
< QUPV3_SE_MAX
; i
++)
261 qup_common_init(QUP_WRAP0_BASE
);
262 qup_common_init(QUP_WRAP1_BASE
);