1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Support for Intel Camera Imaging ISP subsystem.
4  * Copyright (c) 2010 - 2015, Intel Corporation.
5  */
6 
7 #include "hmm.h"
8 
9 #include "ia_css_types.h"
10 #define __INLINE_SP__
11 #include "sp.h"
12 
13 #include "assert_support.h"
14 #include "ia_css_spctrl.h"
15 #include "ia_css_debug.h"
16 
17 struct spctrl_context_info {
18 	struct ia_css_sp_init_dmem_cfg dmem_config;
19 	u32        spctrl_config_dmem_addr; /* location of dmem_cfg  in SP dmem */
20 	u32        spctrl_state_dmem_addr;
21 	unsigned int    sp_entry;           /* entry function ptr on SP */
22 	ia_css_ptr    code_addr;          /* sp firmware location in host mem-DDR*/
23 	u32        code_size;
24 	char           *program_name;       /* used in case of PLATFORM_SIM */
25 };
26 
27 static struct spctrl_context_info spctrl_cofig_info[N_SP_ID];
28 static bool spctrl_loaded[N_SP_ID] = {0};
29 
30 /* Load firmware */
ia_css_spctrl_load_fw(sp_ID_t sp_id,ia_css_spctrl_cfg * spctrl_cfg)31 int ia_css_spctrl_load_fw(sp_ID_t sp_id, ia_css_spctrl_cfg *spctrl_cfg)
32 {
33 	ia_css_ptr code_addr = mmgr_NULL;
34 	struct ia_css_sp_init_dmem_cfg *init_dmem_cfg;
35 
36 	if ((sp_id >= N_SP_ID) || (!spctrl_cfg))
37 		return -EINVAL;
38 
39 	spctrl_cofig_info[sp_id].code_addr = mmgr_NULL;
40 
41 	init_dmem_cfg = &spctrl_cofig_info[sp_id].dmem_config;
42 	init_dmem_cfg->dmem_data_addr = spctrl_cfg->dmem_data_addr;
43 	init_dmem_cfg->dmem_bss_addr  = spctrl_cfg->dmem_bss_addr;
44 	init_dmem_cfg->data_size      = spctrl_cfg->data_size;
45 	init_dmem_cfg->bss_size       = spctrl_cfg->bss_size;
46 	init_dmem_cfg->sp_id          = sp_id;
47 
48 	spctrl_cofig_info[sp_id].spctrl_config_dmem_addr =
49 	    spctrl_cfg->spctrl_config_dmem_addr;
50 	spctrl_cofig_info[sp_id].spctrl_state_dmem_addr =
51 	    spctrl_cfg->spctrl_state_dmem_addr;
52 
53 	/* store code (text + icache) and data to DDR
54 	 *
55 	 * Data used to be stored separately, because of access alignment constraints,
56 	 * fix the FW generation instead
57 	 */
58 	code_addr = hmm_alloc(spctrl_cfg->code_size);
59 	if (code_addr == mmgr_NULL)
60 		return -ENOMEM;
61 	hmm_store(code_addr, spctrl_cfg->code, spctrl_cfg->code_size);
62 
63 	if (sizeof(ia_css_ptr) > sizeof(hrt_data)) {
64 		ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
65 				    "size of ia_css_ptr can not be greater than hrt_data\n");
66 		hmm_free(code_addr);
67 		code_addr = mmgr_NULL;
68 		return -EINVAL;
69 	}
70 
71 	init_dmem_cfg->ddr_data_addr  = code_addr + spctrl_cfg->ddr_data_offset;
72 	if ((init_dmem_cfg->ddr_data_addr % HIVE_ISP_DDR_WORD_BYTES) != 0) {
73 		ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
74 				    "DDR address pointer is not properly aligned for DMA transfer\n");
75 		hmm_free(code_addr);
76 		code_addr = mmgr_NULL;
77 		return -EINVAL;
78 	}
79 
80 	spctrl_cofig_info[sp_id].sp_entry = spctrl_cfg->sp_entry;
81 	spctrl_cofig_info[sp_id].code_addr = code_addr;
82 	spctrl_cofig_info[sp_id].program_name = spctrl_cfg->program_name;
83 
84 	/* now we program the base address into the icache and
85 	 * invalidate the cache.
86 	 */
87 	sp_ctrl_store(sp_id, SP_ICACHE_ADDR_REG,
88 		      (hrt_data)spctrl_cofig_info[sp_id].code_addr);
89 	sp_ctrl_setbit(sp_id, SP_ICACHE_INV_REG, SP_ICACHE_INV_BIT);
90 	spctrl_loaded[sp_id] = true;
91 	return 0;
92 }
93 
94 /* ISP2401 */
95 /* reload pre-loaded FW */
sh_css_spctrl_reload_fw(sp_ID_t sp_id)96 void sh_css_spctrl_reload_fw(sp_ID_t sp_id)
97 {
98 	/* now we program the base address into the icache and
99 	 * invalidate the cache.
100 	 */
101 	sp_ctrl_store(sp_id, SP_ICACHE_ADDR_REG,
102 		      (hrt_data)spctrl_cofig_info[sp_id].code_addr);
103 	sp_ctrl_setbit(sp_id, SP_ICACHE_INV_REG, SP_ICACHE_INV_BIT);
104 	spctrl_loaded[sp_id] = true;
105 }
106 
get_sp_code_addr(sp_ID_t sp_id)107 ia_css_ptr get_sp_code_addr(sp_ID_t  sp_id)
108 {
109 	return spctrl_cofig_info[sp_id].code_addr;
110 }
111 
ia_css_spctrl_unload_fw(sp_ID_t sp_id)112 int ia_css_spctrl_unload_fw(sp_ID_t sp_id)
113 {
114 	if ((sp_id >= N_SP_ID) || ((sp_id < N_SP_ID) && (!spctrl_loaded[sp_id])))
115 		return -EINVAL;
116 
117 	/*  freeup the resource */
118 	if (spctrl_cofig_info[sp_id].code_addr) {
119 		hmm_free(spctrl_cofig_info[sp_id].code_addr);
120 		spctrl_cofig_info[sp_id].code_addr = mmgr_NULL;
121 	}
122 	spctrl_loaded[sp_id] = false;
123 	return 0;
124 }
125 
126 /* Initialize dmem_cfg in SP dmem  and  start SP program*/
ia_css_spctrl_start(sp_ID_t sp_id)127 int ia_css_spctrl_start(sp_ID_t sp_id)
128 {
129 	if ((sp_id >= N_SP_ID) || ((sp_id < N_SP_ID) && (!spctrl_loaded[sp_id])))
130 		return -EINVAL;
131 
132 	/* Set descr in the SP to initialize the SP DMEM */
133 	/*
134 	 * The FW stores user-space pointers to the FW, the ISP pointer
135 	 * is only available here
136 	 *
137 	 */
138 	assert(sizeof(unsigned int) <= sizeof(hrt_data));
139 
140 	sp_dmem_store(sp_id,
141 		      spctrl_cofig_info[sp_id].spctrl_config_dmem_addr,
142 		      &spctrl_cofig_info[sp_id].dmem_config,
143 		      sizeof(spctrl_cofig_info[sp_id].dmem_config));
144 	/* set the start address */
145 	sp_ctrl_store(sp_id, SP_START_ADDR_REG,
146 		      (hrt_data)spctrl_cofig_info[sp_id].sp_entry);
147 	sp_ctrl_setbit(sp_id, SP_SC_REG, SP_RUN_BIT);
148 	sp_ctrl_setbit(sp_id, SP_SC_REG, SP_START_BIT);
149 	return 0;
150 }
151 
152 /* Query the state of SP1 */
ia_css_spctrl_get_state(sp_ID_t sp_id)153 ia_css_spctrl_sp_sw_state ia_css_spctrl_get_state(sp_ID_t sp_id)
154 {
155 	ia_css_spctrl_sp_sw_state state = 0;
156 	unsigned int HIVE_ADDR_sp_sw_state;
157 
158 	if (sp_id >= N_SP_ID)
159 		return IA_CSS_SP_SW_TERMINATED;
160 
161 	HIVE_ADDR_sp_sw_state = spctrl_cofig_info[sp_id].spctrl_state_dmem_addr;
162 	(void)HIVE_ADDR_sp_sw_state; /* Suppres warnings in CRUN */
163 	if (sp_id == SP0_ID)
164 		state = sp_dmem_load_uint32(sp_id, (unsigned int)sp_address_of(sp_sw_state));
165 	return state;
166 }
167 
ia_css_spctrl_is_idle(sp_ID_t sp_id)168 int ia_css_spctrl_is_idle(sp_ID_t sp_id)
169 {
170 	int state = 0;
171 
172 	assert(sp_id < N_SP_ID);
173 
174 	state = sp_ctrl_getbit(sp_id, SP_SC_REG, SP_IDLE_BIT);
175 	return state;
176 }
177