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_1.h" 30 31 static const unsigned int isp_4_1_1_int_srcid[MAX_ISP411_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_1_hw_init(struct amdgpu_isp *isp) 43 { 44 struct amdgpu_device *adev = isp->adev; 45 int idx, int_idx, num_res, r; 46 u64 isp_base; 47 48 if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289) 49 return -EINVAL; 50 51 isp_base = adev->rmmio_base; 52 53 isp->isp_cell = kcalloc(3, sizeof(struct mfd_cell), GFP_KERNEL); 54 if (!isp->isp_cell) { 55 r = -ENOMEM; 56 drm_err(&adev->ddev, 57 "%s: isp mfd cell alloc failed\n", __func__); 58 goto failure; 59 } 60 61 num_res = MAX_ISP411_MEM_RES + MAX_ISP411_INT_SRC; 62 63 isp->isp_res = kcalloc(num_res, sizeof(struct resource), 64 GFP_KERNEL); 65 if (!isp->isp_res) { 66 r = -ENOMEM; 67 drm_err(&adev->ddev, 68 "%s: isp mfd res alloc failed\n", __func__); 69 goto failure; 70 } 71 72 isp->isp_pdata = kzalloc(sizeof(*isp->isp_pdata), GFP_KERNEL); 73 if (!isp->isp_pdata) { 74 r = -ENOMEM; 75 drm_err(&adev->ddev, 76 "%s: isp platform data alloc failed\n", __func__); 77 goto failure; 78 } 79 80 /* initialize isp platform data */ 81 isp->isp_pdata->adev = (void *)adev; 82 isp->isp_pdata->asic_type = adev->asic_type; 83 isp->isp_pdata->base_rmmio_size = adev->rmmio_size; 84 85 isp->isp_res[0].name = "isp_4_1_1_reg"; 86 isp->isp_res[0].flags = IORESOURCE_MEM; 87 isp->isp_res[0].start = isp_base; 88 isp->isp_res[0].end = isp_base + ISP_REGS_OFFSET_END; 89 90 isp->isp_res[1].name = "isp_4_1_1_phy0_reg"; 91 isp->isp_res[1].flags = IORESOURCE_MEM; 92 isp->isp_res[1].start = isp_base + ISP411_PHY0_OFFSET; 93 isp->isp_res[1].end = isp_base + ISP411_PHY0_OFFSET + ISP411_PHY0_SIZE; 94 95 for (idx = MAX_ISP411_MEM_RES, int_idx = 0; idx < num_res; idx++, int_idx++) { 96 isp->isp_res[idx].name = "isp_4_1_1_irq"; 97 isp->isp_res[idx].flags = IORESOURCE_IRQ; 98 isp->isp_res[idx].start = 99 amdgpu_irq_create_mapping(adev, isp_4_1_1_int_srcid[int_idx]); 100 isp->isp_res[idx].end = 101 isp->isp_res[idx].start; 102 } 103 104 isp->isp_cell[0].name = "amd_isp_capture"; 105 isp->isp_cell[0].num_resources = num_res; 106 isp->isp_cell[0].resources = &isp->isp_res[0]; 107 isp->isp_cell[0].platform_data = isp->isp_pdata; 108 isp->isp_cell[0].pdata_size = sizeof(struct isp_platform_data); 109 110 /* initialize isp i2c platform data */ 111 isp->isp_i2c_res = kcalloc(1, sizeof(struct resource), GFP_KERNEL); 112 if (!isp->isp_i2c_res) { 113 r = -ENOMEM; 114 drm_err(&adev->ddev, 115 "%s: isp mfd res alloc failed\n", __func__); 116 goto failure; 117 } 118 119 isp->isp_i2c_res[0].name = "isp_i2c0_reg"; 120 isp->isp_i2c_res[0].flags = IORESOURCE_MEM; 121 isp->isp_i2c_res[0].start = isp_base + ISP411_I2C0_OFFSET; 122 isp->isp_i2c_res[0].end = isp_base + ISP411_I2C0_OFFSET + ISP411_I2C0_SIZE; 123 124 isp->isp_cell[1].name = "amd_isp_i2c_designware"; 125 isp->isp_cell[1].num_resources = 1; 126 isp->isp_cell[1].resources = &isp->isp_i2c_res[0]; 127 isp->isp_cell[1].platform_data = isp->isp_pdata; 128 isp->isp_cell[1].pdata_size = sizeof(struct isp_platform_data); 129 130 /* initialize isp gpiochip platform data */ 131 isp->isp_gpio_res = kcalloc(1, sizeof(struct resource), GFP_KERNEL); 132 if (!isp->isp_gpio_res) { 133 r = -ENOMEM; 134 drm_err(&adev->ddev, 135 "%s: isp gpio res alloc failed\n", __func__); 136 goto failure; 137 } 138 139 isp->isp_gpio_res[0].name = "isp_gpio_reg"; 140 isp->isp_gpio_res[0].flags = IORESOURCE_MEM; 141 isp->isp_gpio_res[0].start = isp_base + ISP411_GPIO_SENSOR_OFFSET; 142 isp->isp_gpio_res[0].end = isp_base + ISP411_GPIO_SENSOR_OFFSET + 143 ISP411_GPIO_SENSOR_SIZE; 144 145 isp->isp_cell[2].name = "amdisp-pinctrl"; 146 isp->isp_cell[2].num_resources = 1; 147 isp->isp_cell[2].resources = &isp->isp_gpio_res[0]; 148 isp->isp_cell[2].platform_data = isp->isp_pdata; 149 isp->isp_cell[2].pdata_size = sizeof(struct isp_platform_data); 150 151 r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 3); 152 if (r) { 153 drm_err(&adev->ddev, 154 "%s: add mfd hotplug device failed\n", __func__); 155 goto failure; 156 } 157 158 return 0; 159 160 failure: 161 162 kfree(isp->isp_pdata); 163 kfree(isp->isp_res); 164 kfree(isp->isp_cell); 165 kfree(isp->isp_i2c_res); 166 kfree(isp->isp_gpio_res); 167 168 return r; 169 } 170 171 static int isp_v4_1_1_hw_fini(struct amdgpu_isp *isp) 172 { 173 mfd_remove_devices(isp->parent); 174 175 kfree(isp->isp_res); 176 kfree(isp->isp_cell); 177 kfree(isp->isp_pdata); 178 kfree(isp->isp_i2c_res); 179 kfree(isp->isp_gpio_res); 180 181 return 0; 182 } 183 184 static const struct isp_funcs isp_v4_1_1_funcs = { 185 .hw_init = isp_v4_1_1_hw_init, 186 .hw_fini = isp_v4_1_1_hw_fini, 187 }; 188 189 void isp_v4_1_1_set_isp_funcs(struct amdgpu_isp *isp) 190 { 191 isp->funcs = &isp_v4_1_1_funcs; 192 } 193