33 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
44 */
55
6+ #include <linux/device.h>
67#include <linux/firmware.h>
78#include <linux/firmware/qcom/qcom_scm.h>
9+ #include <linux/iommu.h>
10+ #include <linux/of.h>
811#include <linux/of_address.h>
12+ #include <linux/of_device.h>
913#include <linux/of_reserved_mem.h>
14+ #include <linux/platform_device.h>
1015#include <linux/soc/qcom/mdt_loader.h>
1116
1217#include "iris_core.h"
1722static int iris_load_fw_to_memory (struct iris_core * core , const char * fw_name )
1823{
1924 u32 pas_id = core -> iris_platform_data -> pas_id ;
25+ struct qcom_scm_pas_context * ctx ;
2026 const struct firmware * firmware = NULL ;
2127 struct device * dev = core -> dev ;
2228 struct reserved_mem * rmem ;
@@ -42,6 +48,14 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
4248 mem_phys = rmem -> base ;
4349 res_size = rmem -> size ;
4450
51+ dev = core -> fw .dev ? : core -> dev ;
52+
53+ ctx = devm_qcom_scm_pas_context_alloc (dev , pas_id , mem_phys , res_size );
54+ if (!ctx )
55+ return - ENOMEM ;
56+
57+ ctx -> use_tzmem = core -> fw .dev ;
58+
4559 ret = request_firmware (& firmware , fw_name , dev );
4660 if (ret )
4761 return ret ;
@@ -58,9 +72,29 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
5872 goto err_release_fw ;
5973 }
6074
61- ret = qcom_mdt_load (dev , firmware , fw_name ,
62- pas_id , mem_virt , mem_phys , res_size , NULL );
75+ ret = qcom_mdt_pas_load (ctx , firmware , fw_name , mem_virt , NULL );
76+ qcom_scm_pas_metadata_release (ctx );
77+ if (ret )
78+ goto err_mem_unmap ;
79+
80+ if (core -> fw .iommu_domain ) {
81+ ret = iommu_map (core -> fw .iommu_domain , 0 , mem_phys , res_size ,
82+ IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV , GFP_KERNEL );
83+ if (ret )
84+ goto err_mem_unmap ;
85+ }
6386
87+ ret = qcom_scm_pas_prepare_and_auth_reset (ctx );
88+ if (ret )
89+ goto err_iommu_unmap ;
90+
91+ core -> fw .ctx = ctx ;
92+
93+ return ret ;
94+
95+ err_iommu_unmap :
96+ iommu_unmap (core -> fw .iommu_domain , 0 , res_size );
97+ err_mem_unmap :
6498 memunmap (mem_virt );
6599err_release_fw :
66100 release_firmware (firmware );
@@ -85,19 +119,13 @@ int iris_fw_load(struct iris_core *core)
85119 return - ENOMEM ;
86120 }
87121
88- ret = qcom_scm_pas_auth_and_reset (core -> iris_platform_data -> pas_id );
89- if (ret ) {
90- dev_err (core -> dev , "auth and reset failed: %d\n" , ret );
91- return ret ;
92- }
93-
94122 ret = qcom_scm_mem_protect_video_var (cp_config -> cp_start ,
95123 cp_config -> cp_size ,
96124 cp_config -> cp_nonpixel_start ,
97125 cp_config -> cp_nonpixel_size );
98126 if (ret ) {
99127 dev_err (core -> dev , "protect memory failed\n" );
100- qcom_scm_pas_shutdown (core -> iris_platform_data -> pas_id );
128+ iris_fw_unload (core );
101129 return ret ;
102130 }
103131
@@ -106,10 +134,91 @@ int iris_fw_load(struct iris_core *core)
106134
107135int iris_fw_unload (struct iris_core * core )
108136{
109- return qcom_scm_pas_shutdown (core -> iris_platform_data -> pas_id );
137+ struct qcom_scm_pas_context * ctx = core -> fw .ctx ;
138+ int ret ;
139+
140+ if (!ctx )
141+ return - EINVAL ;
142+
143+ ret = qcom_scm_pas_shutdown (ctx -> pas_id );
144+ if (core -> fw .iommu_domain )
145+ iommu_unmap (core -> fw .iommu_domain , 0 , ctx -> mem_size );
146+
147+ core -> fw .ctx = NULL ;
148+ return ret ;
110149}
111150
112151int iris_set_hw_state (struct iris_core * core , bool resume )
113152{
114153 return qcom_scm_set_remote_state (resume , 0 );
115154}
155+
156+ int iris_fw_init (struct iris_core * core )
157+ {
158+ struct platform_device_info info ;
159+ struct iommu_domain * iommu_dom ;
160+ struct platform_device * pdev ;
161+ struct device_node * np ;
162+ int ret ;
163+
164+ np = of_get_child_by_name (core -> dev -> of_node , "video-firmware" );
165+ if (!np )
166+ return 0 ;
167+
168+ memset (& info , 0 , sizeof (info ));
169+ info .fwnode = & np -> fwnode ;
170+ info .parent = core -> dev ;
171+ info .name = np -> name ;
172+ info .dma_mask = DMA_BIT_MASK (32 );
173+
174+ pdev = platform_device_register_full (& info );
175+ if (IS_ERR (pdev )) {
176+ of_node_put (np );
177+ return PTR_ERR (pdev );
178+ }
179+
180+ pdev -> dev .of_node = np ;
181+
182+ ret = of_dma_configure (& pdev -> dev , np , true);
183+ if (ret )
184+ goto err_unregister ;
185+
186+ core -> fw .dev = & pdev -> dev ;
187+
188+ iommu_dom = iommu_get_domain_for_dev (core -> fw .dev );
189+ if (!iommu_dom ) {
190+ ret = - EINVAL ;
191+ goto err_unset_fw_dev ;
192+ }
193+
194+ ret = iommu_attach_device (iommu_dom , core -> fw .dev );
195+ if (ret )
196+ goto err_unset_fw_dev ;
197+
198+ core -> fw .iommu_domain = iommu_dom ;
199+
200+ of_node_put (np );
201+
202+ return 0 ;
203+
204+ err_unset_fw_dev :
205+ core -> fw .dev = NULL ;
206+ err_unregister :
207+ platform_device_unregister (pdev );
208+ of_node_put (np );
209+ return ret ;
210+ }
211+
212+ void iris_fw_deinit (struct iris_core * core )
213+ {
214+ if (!core -> fw .dev )
215+ return ;
216+
217+ if (core -> fw .iommu_domain ) {
218+ iommu_detach_device (core -> fw .iommu_domain , core -> fw .dev );
219+ core -> fw .iommu_domain = NULL ;
220+ }
221+
222+ platform_device_unregister (to_platform_device (core -> fw .dev ));
223+ core -> fw .dev = NULL ;
224+ }
0 commit comments