Browse Source

msm: eva: Added QOS registers settings

Changes made to accommodate difference in QOS & NOC
base registers offsets between pineapple and cliffs.

Change-Id: If8c631480d1f09bac21de52d0f27f0c29cdf594e
Signed-off-by: Palak Joshi <[email protected]>
Palak Joshi 1 năm trước cách đây
mục cha
commit
65910f2681
5 tập tin đã thay đổi với 208 bổ sung78 xóa
  1. 121 60
      msm/eva/cvp_hfi.c
  2. 17 17
      msm/eva/cvp_hfi_io.h
  3. 51 1
      msm/eva/msm_cvp_platform.c
  4. 13 0
      msm/eva/msm_cvp_res_parse.c
  5. 6 0
      msm/eva/msm_cvp_resources.h

+ 121 - 60
msm/eva/cvp_hfi.c

@@ -858,50 +858,94 @@ static int __set_registers(struct iris_hfi_device *device)
 
 	__write_register(device, CVP_CPU_CS_AXI4_QOS,
 				pdata->noc_qos->axi_qos);
-	__write_register(device, CVP_NOC_RGE_PRIORITYLUT_LOW,
-				pdata->noc_qos->prioritylut_low);
-	__write_register(device, CVP_NOC_RGE_PRIORITYLUT_HIGH,
-				pdata->noc_qos->prioritylut_high);
-	__write_register(device, CVP_NOC_RGE_URGENCY_LOW,
-				pdata->noc_qos->urgency_low);
-	__write_register(device, CVP_NOC_RGE_DANGERLUT_LOW,
-				pdata->noc_qos->dangerlut_low);
-	__write_register(device, CVP_NOC_RGE_SAFELUT_LOW,
-				pdata->noc_qos->safelut_low);
-	__write_register(device, CVP_NOC_GCE_PRIORITYLUT_LOW,
-				pdata->noc_qos->prioritylut_low);
-	__write_register(device, CVP_NOC_GCE_PRIORITYLUT_HIGH,
-				pdata->noc_qos->prioritylut_high);
-	__write_register(device, CVP_NOC_GCE_URGENCY_LOW,
-				pdata->noc_qos->urgency_low);
-	__write_register(device, CVP_NOC_GCE_DANGERLUT_LOW,
-				pdata->noc_qos->dangerlut_low);
-	__write_register(device, CVP_NOC_GCE_SAFELUT_LOW,
-				pdata->noc_qos->safelut_low);
-	__write_register(device, CVP_NOC_CDM_PRIORITYLUT_LOW,
-				pdata->noc_qos->prioritylut_low);
-	__write_register(device, CVP_NOC_CDM_PRIORITYLUT_HIGH,
-				pdata->noc_qos->prioritylut_high);
-	__write_register(device, CVP_NOC_CDM_URGENCY_LOW,
-				pdata->noc_qos->urgency_low_ro);
-	__write_register(device, CVP_NOC_CDM_DANGERLUT_LOW,
-				pdata->noc_qos->dangerlut_low);
-	__write_register(device, CVP_NOC_CDM_SAFELUT_LOW,
-				pdata->noc_qos->safelut_low);
+	__write_register(device,
+			CVP_NOC_RGE_PRIORITYLUT_LOW +
+			device->res->qos_noc_rge_niu_offset,
+			pdata->noc_qos->prioritylut_low);
+	__write_register(device,
+			CVP_NOC_RGE_PRIORITYLUT_HIGH +
+			device->res->qos_noc_rge_niu_offset,
+			pdata->noc_qos->prioritylut_high);
+	__write_register(device,
+			CVP_NOC_RGE_URGENCY_LOW +
+			device->res->qos_noc_rge_niu_offset,
+			pdata->noc_qos->urgency_low);
+	__write_register(device,
+			CVP_NOC_RGE_DANGERLUT_LOW +
+			device->res->qos_noc_rge_niu_offset,
+			pdata->noc_qos->dangerlut_low);
+	__write_register(device,
+			CVP_NOC_RGE_SAFELUT_LOW +
+			device->res->qos_noc_rge_niu_offset,
+			pdata->noc_qos->safelut_low);
+	__write_register(device,
+			CVP_NOC_GCE_PRIORITYLUT_LOW +
+			device->res->qos_noc_gce_vadl_tof_niu_offset,
+			pdata->noc_qos->prioritylut_low);
+	__write_register(device,
+			CVP_NOC_GCE_PRIORITYLUT_HIGH +
+			device->res->qos_noc_gce_vadl_tof_niu_offset,
+			pdata->noc_qos->prioritylut_high);
+	__write_register(device,
+			CVP_NOC_GCE_URGENCY_LOW +
+			device->res->qos_noc_gce_vadl_tof_niu_offset,
+			pdata->noc_qos->urgency_low);
+	__write_register(device,
+			CVP_NOC_GCE_DANGERLUT_LOW +
+			device->res->qos_noc_gce_vadl_tof_niu_offset,
+			pdata->noc_qos->dangerlut_low);
+	__write_register(device,
+			CVP_NOC_GCE_SAFELUT_LOW +
+			device->res->qos_noc_gce_vadl_tof_niu_offset,
+			pdata->noc_qos->safelut_low);
+
+	__write_register(device,
+			CVP_NOC_CDM_PRIORITYLUT_LOW +
+			device->res->qos_noc_cdm_niu_offset,
+			pdata->noc_qos->prioritylut_low);
+	__write_register(device,
+			CVP_NOC_CDM_PRIORITYLUT_HIGH +
+			device->res->qos_noc_cdm_niu_offset,
+			pdata->noc_qos->prioritylut_high);
+	__write_register(device,
+			CVP_NOC_CDM_URGENCY_LOW +
+			device->res->qos_noc_cdm_niu_offset,
+			pdata->noc_qos->urgency_low_ro);
+	__write_register(device,
+			CVP_NOC_CDM_DANGERLUT_LOW +
+			device->res->qos_noc_cdm_niu_offset,
+			pdata->noc_qos->dangerlut_low);
+	__write_register(device,
+			CVP_NOC_CDM_SAFELUT_LOW +
+			device->res->qos_noc_cdm_niu_offset,
+			pdata->noc_qos->safelut_low);
 
 	/* Below registers write moved from FW to SW to enable UBWC */
-	__write_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW,
-				0x1);
-	__write_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW,
-				0x1);
-	__write_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW,
-				0x1);
-	__write_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW,
-				0x1);
-	__write_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS,
-				0x3);
-	__write_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW,
-				0x1);
+	__write_register(device,
+			CVP_NOC_RGE_NIU_DECCTL_LOW +
+			device->res->qos_noc_rge_niu_offset,
+			0x1);
+	__write_register(device,
+			CVP_NOC_RGE_NIU_ENCCTL_LOW +
+			device->res->qos_noc_rge_niu_offset,
+			0x1);
+	__write_register(device,
+			CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW +
+			device->res->qos_noc_gce_vadl_tof_niu_offset,
+			0x1);
+	__write_register(device,
+			CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW +
+			device->res->qos_noc_gce_vadl_tof_niu_offset,
+			0x1);
+
+	__write_register(device,
+			CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS +
+			device->res->noc_core_err_offset,
+			0x3);
+	__write_register(device,
+			CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW +
+			device->res->noc_main_sidebandmanager_offset,
+			0x1);
 
 	call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset");
 	return 0;
@@ -4633,11 +4677,14 @@ static void __print_sidebandmanager_regs(struct iris_hfi_device *device)
 		goto exit;
 	}
 	main_sbm_ln0_low = __read_register(device,
-			CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW);
+						CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW +
+						device->res->noc_main_sidebandmanager_offset);
 	main_sbm_ln0_high = __read_register(device,
-			CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH);
+						CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH +
+						device->res->noc_main_sidebandmanager_offset);
 	main_sbm_ln1_high = __read_register(device,
-			CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH);
+						CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH +
+						device->res->noc_main_sidebandmanager_offset);
 	call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset");
 
 exit:
@@ -5231,47 +5278,61 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device)
 		return;
 	}
 
-	val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_SWID_LOW_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_swid_low,
 			"CVP_NOC__CORE_ERL_MAIN_SWID_LOW", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_SWID_HIGH_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_swid_high,
 			"CVP_NOC_CORE_ERL_MAIN_SWID_HIGH", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_mainctl_low,
 			"CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_errvld_low,
 			"CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_errclr_low,
 			"CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_errlog0_low,
 			"CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_errlog0_high,
 			"CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_errlog1_low,
 			"CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_errlog1_high,
 			"CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_errlog2_low,
 			"CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_errlog2_high,
 			"CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH", val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS);
-	__err_log(log_required, &noc_log->err_core_errlog3_low, 
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS + device->res->noc_core_err_offset);
+	__err_log(log_required, &noc_log->err_core_errlog3_low,
 			"CORE ERRLOG3_LOW, below details", val);
 	__print_reg_details(val);
-	val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS);
+	val = __read_register(device,
+			CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS + device->res->noc_core_err_offset);
 	__err_log(log_required, &noc_log->err_core_errlog3_high,
 			"CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH", val);
-	__write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS, 0x1);
+	__write_register(device,
+			CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + device->res->noc_core_err_offset, 0x1);
 	call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset");
 #define CVP_SS_CLK_HALT 0x8
 #define CVP_SS_CLK_EN 0xC

+ 17 - 17
msm/eva/cvp_hfi_io.h

@@ -207,39 +207,39 @@
 #define CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW \
 		(CVP_NOC_CORE_BASE_OFFS + 0x3588)
 #define CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW \
-                (CVP_NOC_CORE_BASE_OFFS + 0x7040)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0240)
 #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \
-		(CVP_NOC_CORE_BASE_OFFS + 0x7100)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0300)
 #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH \
-		(CVP_NOC_CORE_BASE_OFFS + 0x7104)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0304)
 #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH \
-		(CVP_NOC_CORE_BASE_OFFS + 0x710C)
+		(CVP_NOC_CORE_BASE_OFFS + 0x030C)
 #define CVP_NOC_CORE_ERR_SWID_LOW_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA000)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0000)
 #define CVP_NOC_CORE_ERR_SWID_HIGH_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA004)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0004)
 #define CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA008)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0008)
 #define CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA010)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0010)
 #define CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA018)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0018)
 #define CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA020)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0020)
 #define CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA024)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0024)
 #define CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA028)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0028)
 #define CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA02C)
+		(CVP_NOC_CORE_BASE_OFFS + 0x002C)
 #define CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA030)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0030)
 #define CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA034)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0034)
 #define CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA038)
+		(CVP_NOC_CORE_BASE_OFFS + 0x0038)
 #define CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS \
-		(CVP_NOC_CORE_BASE_OFFS + 0xA03C)
+		(CVP_NOC_CORE_BASE_OFFS + 0x003C)
 
 #define CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW \
 		(CVP_NOC_CORE_BASE_OFFS + 0x2018)

+ 51 - 1
msm/eva/msm_cvp_platform.c

@@ -249,6 +249,26 @@ static struct msm_cvp_common_data sm8650_common_data[] = {
 	{
 		.key = "qcom,dsp-enabled",
 		.value = 1,
+	},
+	{
+		.key = "qcom,qos_noc_rge_niu_offset",
+		.value = 0x0,
+	},
+	{
+		.key = "qcom,qos_noc_gce_vadl_tof_niu_offset",
+		.value = 0x0,
+	},
+	{
+		.key = "qcom,qos_noc_cdm_niu_offset",
+		.value = 0x0,
+	},
+	{
+		.key = "qcom,noc_core_err_offset",
+		.value = 0xA000,
+	},
+	{
+		.key = "qcom,noc_main_sidebandmanager_offset",
+		.value = 0x6E00,
 	}
 };
 
@@ -292,6 +312,26 @@ static struct msm_cvp_common_data sm7650_common_data[] = {
 	{
 		.key = "qcom,dsp-enabled",
 		.value = 1,
+	},
+	{
+		.key = "qcom,qos_noc_rge_niu_offset",
+		.value = 0x200,
+	},
+	{
+		.key = "qcom,qos_noc_gce_vadl_tof_niu_offset",
+		.value = 0xE00,
+	},
+	{
+		.key = "qcom,qos_noc_cdm_niu_offset",
+		.value = 0x1A00,
+	},
+	{
+		.key = "qcom,noc_core_err_offset",
+		.value = 0x0,
+	},
+	{
+		.key = "qcom,noc_main_sidebandmanager_offset",
+		.value = 0x0,
 	}
 };
 
@@ -319,6 +359,16 @@ static struct msm_cvp_qos_setting lanai_noc_qos = {
 	.safelut_low = 0xffff,
 };
 
+static struct msm_cvp_qos_setting palawan_noc_qos = {
+	.axi_qos = 0x99,
+	.prioritylut_low = 0x33333333,
+	.prioritylut_high = 0x33333333,
+	.urgency_low = 0x1003,
+	.urgency_low_ro = 0x1003,
+	.dangerlut_low = 0x0,
+	.safelut_low = 0xffff,
+};
+
 static struct msm_cvp_platform_data default_data = {
 	.common_data = default_common_data,
 	.common_data_length =  ARRAY_SIZE(default_common_data),
@@ -375,7 +425,7 @@ static struct msm_cvp_platform_data sm7650_data = {
 	.sku_version = 0,
 	.vpu_ver = VPU_VERSION_5,
 	.ubwc_config = kona_ubwc_data,	/*Reuse Kona setting*/
-	.noc_qos = &waipio_noc_qos,	/*Reuse Waipio setting*/
+	.noc_qos = &palawan_noc_qos,
 	.vm_id = 1,
 };
 

+ 13 - 0
msm/eva/msm_cvp_res_parse.c

@@ -878,6 +878,19 @@ int cvp_read_platform_resources_from_drv_data(
 	res->non_fatal_pagefaults = find_key_value(platform_data,
 			"qcom,domain-attr-non-fatal-faults");
 
+	//Address offsets for QOS setting.
+	//There are diff between lanai and palawan for QOS register addresses
+	res->qos_noc_rge_niu_offset = find_key_value(platform_data,
+			"qcom,qos_noc_rge_niu_offset");
+	res->qos_noc_gce_vadl_tof_niu_offset = find_key_value(platform_data,
+			"qcom,qos_noc_gce_vadl_tof_niu_offset");
+	res->qos_noc_cdm_niu_offset = find_key_value(platform_data,
+			"qcom,qos_noc_cdm_niu_offset");
+	res->noc_core_err_offset = find_key_value(platform_data,
+			"qcom,noc_core_err_offset");
+	res->noc_main_sidebandmanager_offset = find_key_value(platform_data,
+			"qcom,noc_main_sidebandmanager_offset");
+
 	res->vpu_ver = platform_data->vpu_ver;
 	res->ubwc_config = platform_data->ubwc_config;
 	res->fatal_ssr = false;

+ 6 - 0
msm/eva/msm_cvp_resources.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef __MSM_CVP_RESOURCES_H__
@@ -214,6 +215,11 @@ struct msm_cvp_platform_resources {
 	uint32_t vpu_ver;
 	uint32_t fw_cycles;
 	struct msm_cvp_ubwc_config_data *ubwc_config;
+	uint32_t qos_noc_rge_niu_offset;
+	uint32_t qos_noc_gce_vadl_tof_niu_offset;
+	uint32_t qos_noc_cdm_niu_offset;
+	uint32_t noc_core_err_offset;
+	uint32_t noc_main_sidebandmanager_offset;
 };
 
 static inline bool is_iommu_present(struct msm_cvp_platform_resources *res)