1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Support for Intel Camera Imaging ISP subsystem. 4 * Copyright (c) 2010-2016, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 */ 15 16 #include <linux/kernel.h> 17 18 #include "dma.h" 19 20 #include "assert_support.h" 21 22 #ifndef __INLINE_DMA__ 23 #include "dma_private.h" 24 #endif /* __INLINE_DMA__ */ 25 26 void dma_get_state(const dma_ID_t ID, dma_state_t *state) 27 { 28 int i; 29 hrt_data tmp; 30 31 assert(ID < N_DMA_ID); 32 assert(state); 33 34 tmp = dma_reg_load(ID, DMA_COMMAND_FSM_REG_IDX); 35 //reg [3:0] : flags error [3], stall, run, idle [0] 36 //reg [9:4] : command 37 //reg[14:10] : channel 38 //reg [23:15] : param 39 state->fsm_command_idle = tmp & 0x1; 40 state->fsm_command_run = tmp & 0x2; 41 state->fsm_command_stalling = tmp & 0x4; 42 state->fsm_command_error = tmp & 0x8; 43 state->last_command_channel = (tmp >> 10 & 0x1F); 44 state->last_command_param = (tmp >> 15 & 0x0F); 45 tmp = (tmp >> 4) & 0x3F; 46 /* state->last_command = (dma_commands_t)tmp; */ 47 /* if the enumerator is made non-linear */ 48 /* AM: the list below does not cover all the cases*/ 49 /* and these are not correct */ 50 /* therefore for just dumpinmg this command*/ 51 state->last_command = tmp; 52 53 /* 54 if (tmp == 0) 55 state->last_command = DMA_COMMAND_READ; 56 if (tmp == 1) 57 state->last_command = DMA_COMMAND_WRITE; 58 if (tmp == 2) 59 state->last_command = DMA_COMMAND_SET_CHANNEL; 60 if (tmp == 3) 61 state->last_command = DMA_COMMAND_SET_PARAM; 62 if (tmp == 4) 63 state->last_command = DMA_COMMAND_READ_SPECIFIC; 64 if (tmp == 5) 65 state->last_command = DMA_COMMAND_WRITE_SPECIFIC; 66 if (tmp == 8) 67 state->last_command = DMA_COMMAND_INIT; 68 if (tmp == 12) 69 state->last_command = DMA_COMMAND_INIT_SPECIFIC; 70 if (tmp == 15) 71 state->last_command = DMA_COMMAND_RST; 72 */ 73 74 /* No sub-fields, idx = 0 */ 75 state->current_command = dma_reg_load(ID, 76 DMA_CG_INFO_REG_IDX(0, _DMA_FSM_GROUP_CMD_IDX)); 77 state->current_addr_a = dma_reg_load(ID, 78 DMA_CG_INFO_REG_IDX(0, _DMA_FSM_GROUP_ADDR_A_IDX)); 79 state->current_addr_b = dma_reg_load(ID, 80 DMA_CG_INFO_REG_IDX(0, _DMA_FSM_GROUP_ADDR_B_IDX)); 81 82 tmp = dma_reg_load(ID, 83 DMA_CG_INFO_REG_IDX( 84 _DMA_FSM_GROUP_FSM_CTRL_STATE_IDX, 85 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 86 state->fsm_ctrl_idle = tmp & 0x1; 87 state->fsm_ctrl_run = tmp & 0x2; 88 state->fsm_ctrl_stalling = tmp & 0x4; 89 state->fsm_ctrl_error = tmp & 0x8; 90 tmp = tmp >> 4; 91 /* state->fsm_ctrl_state = (dma_ctrl_states_t)tmp; */ 92 if (tmp == 0) 93 state->fsm_ctrl_state = DMA_CTRL_STATE_IDLE; 94 if (tmp == 1) 95 state->fsm_ctrl_state = DMA_CTRL_STATE_REQ_RCV; 96 if (tmp == 2) 97 state->fsm_ctrl_state = DMA_CTRL_STATE_RCV; 98 if (tmp == 3) 99 state->fsm_ctrl_state = DMA_CTRL_STATE_RCV_REQ; 100 if (tmp == 4) 101 state->fsm_ctrl_state = DMA_CTRL_STATE_INIT; 102 state->fsm_ctrl_source_dev = dma_reg_load(ID, 103 DMA_CG_INFO_REG_IDX( 104 _DMA_FSM_GROUP_FSM_CTRL_REQ_DEV_IDX, 105 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 106 state->fsm_ctrl_source_addr = dma_reg_load(ID, 107 DMA_CG_INFO_REG_IDX( 108 _DMA_FSM_GROUP_FSM_CTRL_REQ_ADDR_IDX, 109 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 110 state->fsm_ctrl_source_stride = dma_reg_load(ID, 111 DMA_CG_INFO_REG_IDX( 112 _DMA_FSM_GROUP_FSM_CTRL_REQ_STRIDE_IDX, 113 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 114 state->fsm_ctrl_source_width = dma_reg_load(ID, 115 DMA_CG_INFO_REG_IDX( 116 _DMA_FSM_GROUP_FSM_CTRL_REQ_XB_IDX, 117 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 118 state->fsm_ctrl_source_height = dma_reg_load(ID, 119 DMA_CG_INFO_REG_IDX( 120 _DMA_FSM_GROUP_FSM_CTRL_REQ_YB_IDX, 121 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 122 state->fsm_ctrl_pack_source_dev = dma_reg_load(ID, 123 DMA_CG_INFO_REG_IDX( 124 _DMA_FSM_GROUP_FSM_CTRL_PACK_REQ_DEV_IDX, 125 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 126 state->fsm_ctrl_pack_dest_dev = dma_reg_load(ID, 127 DMA_CG_INFO_REG_IDX( 128 _DMA_FSM_GROUP_FSM_CTRL_PACK_WR_DEV_IDX, 129 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 130 state->fsm_ctrl_dest_addr = dma_reg_load(ID, 131 DMA_CG_INFO_REG_IDX( 132 _DMA_FSM_GROUP_FSM_CTRL_WR_ADDR_IDX, 133 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 134 state->fsm_ctrl_dest_stride = dma_reg_load(ID, 135 DMA_CG_INFO_REG_IDX( 136 _DMA_FSM_GROUP_FSM_CTRL_WR_STRIDE_IDX, 137 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 138 state->fsm_ctrl_pack_source_width = dma_reg_load(ID, 139 DMA_CG_INFO_REG_IDX( 140 _DMA_FSM_GROUP_FSM_CTRL_PACK_REQ_XB_IDX, 141 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 142 state->fsm_ctrl_pack_dest_height = dma_reg_load(ID, 143 DMA_CG_INFO_REG_IDX( 144 _DMA_FSM_GROUP_FSM_CTRL_PACK_WR_YB_IDX, 145 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 146 state->fsm_ctrl_pack_dest_width = dma_reg_load(ID, 147 DMA_CG_INFO_REG_IDX( 148 _DMA_FSM_GROUP_FSM_CTRL_PACK_WR_XB_IDX, 149 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 150 state->fsm_ctrl_pack_source_elems = dma_reg_load(ID, 151 DMA_CG_INFO_REG_IDX( 152 _DMA_FSM_GROUP_FSM_CTRL_PACK_ELEM_REQ_IDX, 153 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 154 state->fsm_ctrl_pack_dest_elems = dma_reg_load(ID, 155 DMA_CG_INFO_REG_IDX( 156 _DMA_FSM_GROUP_FSM_CTRL_PACK_ELEM_WR_IDX, 157 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 158 state->fsm_ctrl_pack_extension = dma_reg_load(ID, 159 DMA_CG_INFO_REG_IDX( 160 _DMA_FSM_GROUP_FSM_CTRL_PACK_S_Z_IDX, 161 _DMA_FSM_GROUP_FSM_CTRL_IDX)); 162 163 tmp = dma_reg_load(ID, 164 DMA_CG_INFO_REG_IDX( 165 _DMA_FSM_GROUP_FSM_PACK_STATE_IDX, 166 _DMA_FSM_GROUP_FSM_PACK_IDX)); 167 state->pack_idle = tmp & 0x1; 168 state->pack_run = tmp & 0x2; 169 state->pack_stalling = tmp & 0x4; 170 state->pack_error = tmp & 0x8; 171 state->pack_cnt_height = dma_reg_load(ID, 172 DMA_CG_INFO_REG_IDX( 173 _DMA_FSM_GROUP_FSM_PACK_CNT_YB_IDX, 174 _DMA_FSM_GROUP_FSM_PACK_IDX)); 175 state->pack_src_cnt_width = dma_reg_load(ID, 176 DMA_CG_INFO_REG_IDX( 177 _DMA_FSM_GROUP_FSM_PACK_CNT_XB_REQ_IDX, 178 _DMA_FSM_GROUP_FSM_PACK_IDX)); 179 state->pack_dest_cnt_width = dma_reg_load(ID, 180 DMA_CG_INFO_REG_IDX( 181 _DMA_FSM_GROUP_FSM_PACK_CNT_XB_WR_IDX, 182 _DMA_FSM_GROUP_FSM_PACK_IDX)); 183 184 tmp = dma_reg_load(ID, 185 DMA_CG_INFO_REG_IDX( 186 _DMA_FSM_GROUP_FSM_REQ_STATE_IDX, 187 _DMA_FSM_GROUP_FSM_REQ_IDX)); 188 /* state->read_state = (dma_rw_states_t)tmp; */ 189 if (tmp == 0) 190 state->read_state = DMA_RW_STATE_IDLE; 191 if (tmp == 1) 192 state->read_state = DMA_RW_STATE_REQ; 193 if (tmp == 2) 194 state->read_state = DMA_RW_STATE_NEXT_LINE; 195 if (tmp == 3) 196 state->read_state = DMA_RW_STATE_UNLOCK_CHANNEL; 197 state->read_cnt_height = dma_reg_load(ID, 198 DMA_CG_INFO_REG_IDX( 199 _DMA_FSM_GROUP_FSM_REQ_CNT_YB_IDX, 200 _DMA_FSM_GROUP_FSM_REQ_IDX)); 201 state->read_cnt_width = dma_reg_load(ID, 202 DMA_CG_INFO_REG_IDX( 203 _DMA_FSM_GROUP_FSM_REQ_CNT_XB_IDX, 204 _DMA_FSM_GROUP_FSM_REQ_IDX)); 205 206 tmp = dma_reg_load(ID, 207 DMA_CG_INFO_REG_IDX( 208 _DMA_FSM_GROUP_FSM_WR_STATE_IDX, 209 _DMA_FSM_GROUP_FSM_WR_IDX)); 210 /* state->write_state = (dma_rw_states_t)tmp; */ 211 if (tmp == 0) 212 state->write_state = DMA_RW_STATE_IDLE; 213 if (tmp == 1) 214 state->write_state = DMA_RW_STATE_REQ; 215 if (tmp == 2) 216 state->write_state = DMA_RW_STATE_NEXT_LINE; 217 if (tmp == 3) 218 state->write_state = DMA_RW_STATE_UNLOCK_CHANNEL; 219 state->write_height = dma_reg_load(ID, 220 DMA_CG_INFO_REG_IDX( 221 _DMA_FSM_GROUP_FSM_WR_CNT_YB_IDX, 222 _DMA_FSM_GROUP_FSM_WR_IDX)); 223 state->write_width = dma_reg_load(ID, 224 DMA_CG_INFO_REG_IDX( 225 _DMA_FSM_GROUP_FSM_WR_CNT_XB_IDX, 226 _DMA_FSM_GROUP_FSM_WR_IDX)); 227 228 for (i = 0; i < HIVE_ISP_NUM_DMA_CONNS; i++) { 229 dma_port_state_t *port = &state->port_states[i]; 230 231 tmp = dma_reg_load(ID, DMA_DEV_INFO_REG_IDX(0, i)); 232 port->req_cs = ((tmp & 0x1) != 0); 233 port->req_we_n = ((tmp & 0x2) != 0); 234 port->req_run = ((tmp & 0x4) != 0); 235 port->req_ack = ((tmp & 0x8) != 0); 236 237 tmp = dma_reg_load(ID, DMA_DEV_INFO_REG_IDX(1, i)); 238 port->send_cs = ((tmp & 0x1) != 0); 239 port->send_we_n = ((tmp & 0x2) != 0); 240 port->send_run = ((tmp & 0x4) != 0); 241 port->send_ack = ((tmp & 0x8) != 0); 242 243 tmp = dma_reg_load(ID, DMA_DEV_INFO_REG_IDX(2, i)); 244 if (tmp & 0x1) 245 port->fifo_state = DMA_FIFO_STATE_WILL_BE_FULL; 246 if (tmp & 0x2) 247 port->fifo_state = DMA_FIFO_STATE_FULL; 248 if (tmp & 0x4) 249 port->fifo_state = DMA_FIFO_STATE_EMPTY; 250 port->fifo_counter = tmp >> 3; 251 } 252 253 for (i = 0; i < HIVE_DMA_NUM_CHANNELS; i++) { 254 dma_channel_state_t *ch = &state->channel_states[i]; 255 256 ch->connection = DMA_GET_CONNECTION(dma_reg_load(ID, 257 DMA_CHANNEL_PARAM_REG_IDX(i, 258 _DMA_PACKING_SETUP_PARAM))); 259 ch->sign_extend = DMA_GET_EXTENSION(dma_reg_load(ID, 260 DMA_CHANNEL_PARAM_REG_IDX(i, 261 _DMA_PACKING_SETUP_PARAM))); 262 ch->height = dma_reg_load(ID, 263 DMA_CHANNEL_PARAM_REG_IDX(i, 264 _DMA_HEIGHT_PARAM)); 265 ch->stride_a = dma_reg_load(ID, 266 DMA_CHANNEL_PARAM_REG_IDX(i, 267 _DMA_STRIDE_A_PARAM)); 268 ch->elems_a = DMA_GET_ELEMENTS(dma_reg_load(ID, 269 DMA_CHANNEL_PARAM_REG_IDX(i, 270 _DMA_ELEM_CROPPING_A_PARAM))); 271 ch->cropping_a = DMA_GET_CROPPING(dma_reg_load(ID, 272 DMA_CHANNEL_PARAM_REG_IDX(i, 273 _DMA_ELEM_CROPPING_A_PARAM))); 274 ch->width_a = dma_reg_load(ID, 275 DMA_CHANNEL_PARAM_REG_IDX(i, 276 _DMA_WIDTH_A_PARAM)); 277 ch->stride_b = dma_reg_load(ID, 278 DMA_CHANNEL_PARAM_REG_IDX(i, 279 _DMA_STRIDE_B_PARAM)); 280 ch->elems_b = DMA_GET_ELEMENTS(dma_reg_load(ID, 281 DMA_CHANNEL_PARAM_REG_IDX(i, 282 _DMA_ELEM_CROPPING_B_PARAM))); 283 ch->cropping_b = DMA_GET_CROPPING(dma_reg_load(ID, 284 DMA_CHANNEL_PARAM_REG_IDX(i, 285 _DMA_ELEM_CROPPING_B_PARAM))); 286 ch->width_b = dma_reg_load(ID, 287 DMA_CHANNEL_PARAM_REG_IDX(i, 288 _DMA_WIDTH_B_PARAM)); 289 } 290 } 291 292 void 293 dma_set_max_burst_size(const dma_ID_t ID, dma_connection conn, 294 uint32_t max_burst_size) 295 { 296 assert(ID < N_DMA_ID); 297 assert(max_burst_size > 0); 298 dma_reg_store(ID, DMA_DEV_INFO_REG_IDX(_DMA_DEV_INTERF_MAX_BURST_IDX, conn), 299 max_burst_size - 1); 300 } 301