105bafe95SPratap Nirujogi /* SPDX-License-Identifier: MIT */
205bafe95SPratap Nirujogi /*
305bafe95SPratap Nirujogi * Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
405bafe95SPratap Nirujogi * All Rights Reserved.
505bafe95SPratap Nirujogi *
605bafe95SPratap Nirujogi * Permission is hereby granted, free of charge, to any person obtaining a
705bafe95SPratap Nirujogi * copy of this software and associated documentation files (the
805bafe95SPratap Nirujogi * "Software"), to deal in the Software without restriction, including
905bafe95SPratap Nirujogi * without limitation the rights to use, copy, modify, merge, publish,
1005bafe95SPratap Nirujogi * distribute, sub license, and/or sell copies of the Software, and to
1105bafe95SPratap Nirujogi * permit persons to whom the Software is furnished to do so, subject to
1205bafe95SPratap Nirujogi * the following conditions:
1305bafe95SPratap Nirujogi *
1405bafe95SPratap Nirujogi * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1505bafe95SPratap Nirujogi * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1605bafe95SPratap Nirujogi * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1705bafe95SPratap Nirujogi * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
1805bafe95SPratap Nirujogi * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
1905bafe95SPratap Nirujogi * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2005bafe95SPratap Nirujogi * USE OR OTHER DEALINGS IN THE SOFTWARE.
2105bafe95SPratap Nirujogi *
2205bafe95SPratap Nirujogi * The above copyright notice and this permission notice (including the
2305bafe95SPratap Nirujogi * next paragraph) shall be included in all copies or substantial portions
2405bafe95SPratap Nirujogi * of the Software.
2505bafe95SPratap Nirujogi *
2605bafe95SPratap Nirujogi */
2705bafe95SPratap Nirujogi
2805bafe95SPratap Nirujogi #include "amdgpu.h"
2905bafe95SPratap Nirujogi #include "isp_v4_1_1.h"
3005bafe95SPratap Nirujogi
3105bafe95SPratap Nirujogi static const unsigned int isp_4_1_1_int_srcid[MAX_ISP411_INT_SRC] = {
3205bafe95SPratap Nirujogi ISP_4_1__SRCID__ISP_RINGBUFFER_WPT9,
3305bafe95SPratap Nirujogi ISP_4_1__SRCID__ISP_RINGBUFFER_WPT10,
3405bafe95SPratap Nirujogi ISP_4_1__SRCID__ISP_RINGBUFFER_WPT11,
3505bafe95SPratap Nirujogi ISP_4_1__SRCID__ISP_RINGBUFFER_WPT12,
3605bafe95SPratap Nirujogi ISP_4_1__SRCID__ISP_RINGBUFFER_WPT13,
3705bafe95SPratap Nirujogi ISP_4_1__SRCID__ISP_RINGBUFFER_WPT14,
3805bafe95SPratap Nirujogi ISP_4_1__SRCID__ISP_RINGBUFFER_WPT15,
3905bafe95SPratap Nirujogi ISP_4_1__SRCID__ISP_RINGBUFFER_WPT16
4005bafe95SPratap Nirujogi };
4105bafe95SPratap Nirujogi
isp_v4_1_1_hw_init(struct amdgpu_isp * isp)4205bafe95SPratap Nirujogi static int isp_v4_1_1_hw_init(struct amdgpu_isp *isp)
4305bafe95SPratap Nirujogi {
4405bafe95SPratap Nirujogi struct amdgpu_device *adev = isp->adev;
45*25dd25f8SVenkata Narendra Kumar Gutta int idx, int_idx, num_res, r;
4605bafe95SPratap Nirujogi u64 isp_base;
4705bafe95SPratap Nirujogi
4805bafe95SPratap Nirujogi if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289)
4905bafe95SPratap Nirujogi return -EINVAL;
5005bafe95SPratap Nirujogi
5105bafe95SPratap Nirujogi isp_base = adev->rmmio_base;
5205bafe95SPratap Nirujogi
53*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_cell = kcalloc(2, sizeof(struct mfd_cell), GFP_KERNEL);
5405bafe95SPratap Nirujogi if (!isp->isp_cell) {
5505bafe95SPratap Nirujogi r = -ENOMEM;
5605bafe95SPratap Nirujogi DRM_ERROR("%s: isp mfd cell alloc failed\n", __func__);
5705bafe95SPratap Nirujogi goto failure;
5805bafe95SPratap Nirujogi }
5905bafe95SPratap Nirujogi
60*25dd25f8SVenkata Narendra Kumar Gutta num_res = MAX_ISP411_MEM_RES + MAX_ISP411_SENSOR_RES + MAX_ISP411_INT_SRC;
61*25dd25f8SVenkata Narendra Kumar Gutta
62*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res = kcalloc(num_res, sizeof(struct resource),
6305bafe95SPratap Nirujogi GFP_KERNEL);
6405bafe95SPratap Nirujogi if (!isp->isp_res) {
6505bafe95SPratap Nirujogi r = -ENOMEM;
6605bafe95SPratap Nirujogi DRM_ERROR("%s: isp mfd res alloc failed\n", __func__);
6705bafe95SPratap Nirujogi goto failure;
6805bafe95SPratap Nirujogi }
6905bafe95SPratap Nirujogi
7005bafe95SPratap Nirujogi isp->isp_pdata = kzalloc(sizeof(*isp->isp_pdata), GFP_KERNEL);
7105bafe95SPratap Nirujogi if (!isp->isp_pdata) {
7205bafe95SPratap Nirujogi r = -ENOMEM;
7305bafe95SPratap Nirujogi DRM_ERROR("%s: isp platform data alloc failed\n", __func__);
7405bafe95SPratap Nirujogi goto failure;
7505bafe95SPratap Nirujogi }
7605bafe95SPratap Nirujogi
7705bafe95SPratap Nirujogi /* initialize isp platform data */
7805bafe95SPratap Nirujogi isp->isp_pdata->adev = (void *)adev;
7905bafe95SPratap Nirujogi isp->isp_pdata->asic_type = adev->asic_type;
8005bafe95SPratap Nirujogi isp->isp_pdata->base_rmmio_size = adev->rmmio_size;
8105bafe95SPratap Nirujogi
8205bafe95SPratap Nirujogi isp->isp_res[0].name = "isp_4_1_1_reg";
8305bafe95SPratap Nirujogi isp->isp_res[0].flags = IORESOURCE_MEM;
8405bafe95SPratap Nirujogi isp->isp_res[0].start = isp_base;
8505bafe95SPratap Nirujogi isp->isp_res[0].end = isp_base + ISP_REGS_OFFSET_END;
8605bafe95SPratap Nirujogi
87*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[1].name = "isp_4_1_1_phy0_reg";
88*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[1].flags = IORESOURCE_MEM;
89*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[1].start = isp_base + ISP411_PHY0_OFFSET;
90*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[1].end = isp_base + ISP411_PHY0_OFFSET + ISP411_PHY0_SIZE;
91*25dd25f8SVenkata Narendra Kumar Gutta
92*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[2].name = "isp_4_1_1_sensor0_reg";
93*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[2].flags = IORESOURCE_MEM;
94*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[2].start = isp_base + ISP411_GPIO_SENSOR0_OFFSET;
95*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[2].end = isp_base + ISP411_GPIO_SENSOR0_OFFSET +
96*25dd25f8SVenkata Narendra Kumar Gutta ISP411_GPIO_SENSOR0_SIZE;
97*25dd25f8SVenkata Narendra Kumar Gutta
98*25dd25f8SVenkata Narendra Kumar Gutta for (idx = MAX_ISP411_MEM_RES + MAX_ISP411_SENSOR_RES, int_idx = 0;
99*25dd25f8SVenkata Narendra Kumar Gutta idx < num_res; idx++, int_idx++) {
100*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[idx].name = "isp_4_1_1_irq";
101*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[idx].flags = IORESOURCE_IRQ;
102*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[idx].start =
10305bafe95SPratap Nirujogi amdgpu_irq_create_mapping(adev, isp_4_1_1_int_srcid[int_idx]);
104*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[idx].end =
105*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_res[idx].start;
10605bafe95SPratap Nirujogi }
10705bafe95SPratap Nirujogi
10805bafe95SPratap Nirujogi isp->isp_cell[0].name = "amd_isp_capture";
109*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_cell[0].num_resources = num_res;
11005bafe95SPratap Nirujogi isp->isp_cell[0].resources = &isp->isp_res[0];
11105bafe95SPratap Nirujogi isp->isp_cell[0].platform_data = isp->isp_pdata;
11205bafe95SPratap Nirujogi isp->isp_cell[0].pdata_size = sizeof(struct isp_platform_data);
11305bafe95SPratap Nirujogi
114*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_i2c_res = kcalloc(1, sizeof(struct resource), GFP_KERNEL);
115*25dd25f8SVenkata Narendra Kumar Gutta if (!isp->isp_i2c_res) {
116*25dd25f8SVenkata Narendra Kumar Gutta r = -ENOMEM;
117*25dd25f8SVenkata Narendra Kumar Gutta DRM_ERROR("%s: isp mfd res alloc failed\n", __func__);
118*25dd25f8SVenkata Narendra Kumar Gutta goto failure;
119*25dd25f8SVenkata Narendra Kumar Gutta }
120*25dd25f8SVenkata Narendra Kumar Gutta
121*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_i2c_res[0].name = "isp_i2c0_reg";
122*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_i2c_res[0].flags = IORESOURCE_MEM;
123*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_i2c_res[0].start = isp_base + ISP411_I2C0_OFFSET;
124*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_i2c_res[0].end = isp_base + ISP411_I2C0_OFFSET + ISP411_I2C0_SIZE;
125*25dd25f8SVenkata Narendra Kumar Gutta
126*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_cell[1].name = "amd_isp_i2c_designware";
127*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_cell[1].num_resources = 1;
128*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_cell[1].resources = &isp->isp_i2c_res[0];
129*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_cell[1].platform_data = isp->isp_pdata;
130*25dd25f8SVenkata Narendra Kumar Gutta isp->isp_cell[1].pdata_size = sizeof(struct isp_platform_data);
131*25dd25f8SVenkata Narendra Kumar Gutta
132*25dd25f8SVenkata Narendra Kumar Gutta r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 2);
13305bafe95SPratap Nirujogi if (r) {
13405bafe95SPratap Nirujogi DRM_ERROR("%s: add mfd hotplug device failed\n", __func__);
13505bafe95SPratap Nirujogi goto failure;
13605bafe95SPratap Nirujogi }
13705bafe95SPratap Nirujogi
13805bafe95SPratap Nirujogi return 0;
13905bafe95SPratap Nirujogi
14005bafe95SPratap Nirujogi failure:
14105bafe95SPratap Nirujogi
14205bafe95SPratap Nirujogi kfree(isp->isp_pdata);
14305bafe95SPratap Nirujogi kfree(isp->isp_res);
14405bafe95SPratap Nirujogi kfree(isp->isp_cell);
145*25dd25f8SVenkata Narendra Kumar Gutta kfree(isp->isp_i2c_res);
14605bafe95SPratap Nirujogi
14705bafe95SPratap Nirujogi return r;
14805bafe95SPratap Nirujogi }
14905bafe95SPratap Nirujogi
isp_v4_1_1_hw_fini(struct amdgpu_isp * isp)15005bafe95SPratap Nirujogi static int isp_v4_1_1_hw_fini(struct amdgpu_isp *isp)
15105bafe95SPratap Nirujogi {
15205bafe95SPratap Nirujogi mfd_remove_devices(isp->parent);
15305bafe95SPratap Nirujogi
15405bafe95SPratap Nirujogi kfree(isp->isp_res);
15505bafe95SPratap Nirujogi kfree(isp->isp_cell);
15605bafe95SPratap Nirujogi kfree(isp->isp_pdata);
157*25dd25f8SVenkata Narendra Kumar Gutta kfree(isp->isp_i2c_res);
15805bafe95SPratap Nirujogi
15905bafe95SPratap Nirujogi return 0;
16005bafe95SPratap Nirujogi }
16105bafe95SPratap Nirujogi
16205bafe95SPratap Nirujogi static const struct isp_funcs isp_v4_1_1_funcs = {
16305bafe95SPratap Nirujogi .hw_init = isp_v4_1_1_hw_init,
16405bafe95SPratap Nirujogi .hw_fini = isp_v4_1_1_hw_fini,
16505bafe95SPratap Nirujogi };
16605bafe95SPratap Nirujogi
isp_v4_1_1_set_isp_funcs(struct amdgpu_isp * isp)16705bafe95SPratap Nirujogi void isp_v4_1_1_set_isp_funcs(struct amdgpu_isp *isp)
16805bafe95SPratap Nirujogi {
16905bafe95SPratap Nirujogi isp->funcs = &isp_v4_1_1_funcs;
17005bafe95SPratap Nirujogi }
171