1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 * 26 */ 27 28 #include "amdgpu.h" 29 #include "isp_v4_1_0.h" 30 31 static const unsigned int isp_4_1_0_int_srcid[MAX_ISP410_INT_SRC] = { 32 ISP_4_1__SRCID__ISP_RINGBUFFER_WPT9, 33 ISP_4_1__SRCID__ISP_RINGBUFFER_WPT10, 34 ISP_4_1__SRCID__ISP_RINGBUFFER_WPT11, 35 ISP_4_1__SRCID__ISP_RINGBUFFER_WPT12, 36 ISP_4_1__SRCID__ISP_RINGBUFFER_WPT13, 37 ISP_4_1__SRCID__ISP_RINGBUFFER_WPT14, 38 ISP_4_1__SRCID__ISP_RINGBUFFER_WPT15, 39 ISP_4_1__SRCID__ISP_RINGBUFFER_WPT16 40 }; 41 42 static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) 43 { 44 struct amdgpu_device *adev = isp->adev; 45 u64 isp_base; 46 int int_idx; 47 int r; 48 49 if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289) 50 return -EINVAL; 51 52 isp_base = adev->rmmio_base; 53 54 isp->isp_cell = kcalloc(1, sizeof(struct mfd_cell), GFP_KERNEL); 55 if (!isp->isp_cell) { 56 r = -ENOMEM; 57 DRM_ERROR("%s: isp mfd cell alloc failed\n", __func__); 58 goto failure; 59 } 60 61 isp->isp_res = kcalloc(MAX_ISP410_INT_SRC + 1, sizeof(struct resource), 62 GFP_KERNEL); 63 if (!isp->isp_res) { 64 r = -ENOMEM; 65 DRM_ERROR("%s: isp mfd res alloc failed\n", __func__); 66 goto failure; 67 } 68 69 isp->isp_pdata = kzalloc(sizeof(*isp->isp_pdata), GFP_KERNEL); 70 if (!isp->isp_pdata) { 71 r = -ENOMEM; 72 DRM_ERROR("%s: isp platform data alloc failed\n", __func__); 73 goto failure; 74 } 75 76 /* initialize isp platform data */ 77 isp->isp_pdata->adev = (void *)adev; 78 isp->isp_pdata->asic_type = adev->asic_type; 79 isp->isp_pdata->base_rmmio_size = adev->rmmio_size; 80 81 isp->isp_res[0].name = "isp_4_1_0_reg"; 82 isp->isp_res[0].flags = IORESOURCE_MEM; 83 isp->isp_res[0].start = isp_base; 84 isp->isp_res[0].end = isp_base + ISP_REGS_OFFSET_END; 85 86 for (int_idx = 0; int_idx < MAX_ISP410_INT_SRC; int_idx++) { 87 isp->isp_res[int_idx + 1].name = "isp_4_1_0_irq"; 88 isp->isp_res[int_idx + 1].flags = IORESOURCE_IRQ; 89 isp->isp_res[int_idx + 1].start = 90 amdgpu_irq_create_mapping(adev, isp_4_1_0_int_srcid[int_idx]); 91 isp->isp_res[int_idx + 1].end = 92 isp->isp_res[int_idx + 1].start; 93 } 94 95 isp->isp_cell[0].name = "amd_isp_capture"; 96 isp->isp_cell[0].num_resources = MAX_ISP410_INT_SRC + 1; 97 isp->isp_cell[0].resources = &isp->isp_res[0]; 98 isp->isp_cell[0].platform_data = isp->isp_pdata; 99 isp->isp_cell[0].pdata_size = sizeof(struct isp_platform_data); 100 101 r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 1); 102 if (r) { 103 DRM_ERROR("%s: add mfd hotplug device failed\n", __func__); 104 goto failure; 105 } 106 107 return 0; 108 109 failure: 110 111 kfree(isp->isp_pdata); 112 kfree(isp->isp_res); 113 kfree(isp->isp_cell); 114 115 return r; 116 } 117 118 static int isp_v4_1_0_hw_fini(struct amdgpu_isp *isp) 119 { 120 mfd_remove_devices(isp->parent); 121 122 kfree(isp->isp_res); 123 kfree(isp->isp_cell); 124 kfree(isp->isp_pdata); 125 126 return 0; 127 } 128 129 static const struct isp_funcs isp_v4_1_0_funcs = { 130 .hw_init = isp_v4_1_0_hw_init, 131 .hw_fini = isp_v4_1_0_hw_fini, 132 }; 133 134 void isp_v4_1_0_set_isp_funcs(struct amdgpu_isp *isp) 135 { 136 isp->funcs = &isp_v4_1_0_funcs; 137 } 138