Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: Add MFD support for ISP I2C bus

ISP I2C bus device can't be enumerated via ACPI mechanism
since it shares the memory map with the AMDGPU.
So use the MFD mechanism for registering the ISP I2C device
and add the required resources.

Signed-off-by: Venkata Narendra Kumar Gutta <vengutta@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Venkata Narendra Kumar Gutta and committed by
Alex Deucher
25dd25f8 fbfb5f03

+113 -24
+1
drivers/gpu/drm/amd/amdgpu/amdgpu_isp.h
··· 49 49 const struct isp_funcs *funcs; 50 50 struct mfd_cell *isp_cell; 51 51 struct resource *isp_res; 52 + struct resource *isp_i2c_res; 52 53 struct isp_platform_data *isp_pdata; 53 54 unsigned int harvest_config; 54 55 const struct firmware *fw;
+45 -12
drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c
··· 42 42 static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) 43 43 { 44 44 struct amdgpu_device *adev = isp->adev; 45 + int idx, int_idx, num_res, r; 45 46 u64 isp_base; 46 - int int_idx; 47 - int r; 48 47 49 48 if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289) 50 49 return -EINVAL; 51 50 52 51 isp_base = adev->rmmio_base; 53 52 54 - isp->isp_cell = kcalloc(1, sizeof(struct mfd_cell), GFP_KERNEL); 53 + isp->isp_cell = kcalloc(2, sizeof(struct mfd_cell), GFP_KERNEL); 55 54 if (!isp->isp_cell) { 56 55 r = -ENOMEM; 57 56 DRM_ERROR("%s: isp mfd cell alloc failed\n", __func__); 58 57 goto failure; 59 58 } 60 59 61 - isp->isp_res = kcalloc(MAX_ISP410_INT_SRC + 1, sizeof(struct resource), 60 + num_res = MAX_ISP410_MEM_RES + MAX_ISP410_SENSOR_RES + MAX_ISP410_INT_SRC; 61 + isp->isp_res = kcalloc(num_res, sizeof(struct resource), 62 62 GFP_KERNEL); 63 63 if (!isp->isp_res) { 64 64 r = -ENOMEM; ··· 83 83 isp->isp_res[0].start = isp_base; 84 84 isp->isp_res[0].end = isp_base + ISP_REGS_OFFSET_END; 85 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 = 86 + isp->isp_res[1].name = "isp_4_1_phy0_reg"; 87 + isp->isp_res[1].flags = IORESOURCE_MEM; 88 + isp->isp_res[1].start = isp_base + ISP410_PHY0_OFFSET; 89 + isp->isp_res[1].end = isp_base + ISP410_PHY0_OFFSET + ISP410_PHY0_SIZE; 90 + 91 + isp->isp_res[2].name = "isp_gpio_sensor0_reg"; 92 + isp->isp_res[2].flags = IORESOURCE_MEM; 93 + isp->isp_res[2].start = isp_base + ISP410_GPIO_SENSOR0_OFFSET; 94 + isp->isp_res[2].end = isp_base + ISP410_GPIO_SENSOR0_OFFSET + 95 + ISP410_GPIO_SENSOR0_SIZE; 96 + 97 + for (idx = MAX_ISP410_MEM_RES + MAX_ISP410_SENSOR_RES, int_idx = 0; 98 + idx < num_res; idx++, int_idx++) { 99 + isp->isp_res[idx].name = "isp_4_1_0_irq"; 100 + isp->isp_res[idx].flags = IORESOURCE_IRQ; 101 + isp->isp_res[idx].start = 90 102 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; 103 + isp->isp_res[idx].end = 104 + isp->isp_res[idx].start; 93 105 } 94 106 95 107 isp->isp_cell[0].name = "amd_isp_capture"; 96 - isp->isp_cell[0].num_resources = MAX_ISP410_INT_SRC + 1; 108 + isp->isp_cell[0].num_resources = num_res; 97 109 isp->isp_cell[0].resources = &isp->isp_res[0]; 98 110 isp->isp_cell[0].platform_data = isp->isp_pdata; 99 111 isp->isp_cell[0].pdata_size = sizeof(struct isp_platform_data); 100 112 101 - r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 1); 113 + isp->isp_i2c_res = kcalloc(1, sizeof(struct resource), 114 + GFP_KERNEL); 115 + if (!isp->isp_i2c_res) { 116 + r = -ENOMEM; 117 + DRM_ERROR("%s: isp mfd res alloc failed\n", __func__); 118 + goto failure; 119 + } 120 + 121 + isp->isp_i2c_res[0].name = "isp_i2c0_reg"; 122 + isp->isp_i2c_res[0].flags = IORESOURCE_MEM; 123 + isp->isp_i2c_res[0].start = isp_base + ISP410_I2C0_OFFSET; 124 + isp->isp_i2c_res[0].end = isp_base + ISP410_I2C0_OFFSET + ISP410_I2C0_SIZE; 125 + 126 + isp->isp_cell[1].name = "amd_isp_i2c_designware"; 127 + isp->isp_cell[1].num_resources = 1; 128 + isp->isp_cell[1].resources = &isp->isp_i2c_res[0]; 129 + isp->isp_cell[1].platform_data = isp->isp_pdata; 130 + isp->isp_cell[1].pdata_size = sizeof(struct isp_platform_data); 131 + 132 + r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 2); 102 133 if (r) { 103 134 DRM_ERROR("%s: add mfd hotplug device failed\n", __func__); 104 135 goto failure; ··· 142 111 kfree(isp->isp_pdata); 143 112 kfree(isp->isp_res); 144 113 kfree(isp->isp_cell); 114 + kfree(isp->isp_i2c_res); 145 115 146 116 return r; 147 117 } ··· 154 122 kfree(isp->isp_res); 155 123 kfree(isp->isp_cell); 156 124 kfree(isp->isp_pdata); 125 + kfree(isp->isp_i2c_res); 157 126 158 127 return 0; 159 128 }
+11
drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.h
··· 32 32 33 33 #include "ivsrcid/isp/irqsrcs_isp_4_1.h" 34 34 35 + #define MAX_ISP410_MEM_RES 2 36 + #define MAX_ISP410_SENSOR_RES 1 35 37 #define MAX_ISP410_INT_SRC 8 38 + 39 + #define ISP410_PHY0_OFFSET 0x66700 40 + #define ISP410_PHY0_SIZE 0xD30 41 + 42 + #define ISP410_I2C0_OFFSET 0x66400 43 + #define ISP410_I2C0_SIZE 0x100 44 + 45 + #define ISP410_GPIO_SENSOR0_OFFSET 0x6613C 46 + #define ISP410_GPIO_SENSOR0_SIZE 0x4 36 47 37 48 void isp_v4_1_0_set_isp_funcs(struct amdgpu_isp *isp); 38 49
+45 -12
drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c
··· 42 42 static int isp_v4_1_1_hw_init(struct amdgpu_isp *isp) 43 43 { 44 44 struct amdgpu_device *adev = isp->adev; 45 + int idx, int_idx, num_res, r; 45 46 u64 isp_base; 46 - int int_idx; 47 - int r; 48 47 49 48 if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289) 50 49 return -EINVAL; 51 50 52 51 isp_base = adev->rmmio_base; 53 52 54 - isp->isp_cell = kcalloc(1, sizeof(struct mfd_cell), GFP_KERNEL); 53 + isp->isp_cell = kcalloc(2, sizeof(struct mfd_cell), GFP_KERNEL); 55 54 if (!isp->isp_cell) { 56 55 r = -ENOMEM; 57 56 DRM_ERROR("%s: isp mfd cell alloc failed\n", __func__); 58 57 goto failure; 59 58 } 60 59 61 - isp->isp_res = kcalloc(MAX_ISP411_INT_SRC + 1, sizeof(struct resource), 60 + num_res = MAX_ISP411_MEM_RES + MAX_ISP411_SENSOR_RES + MAX_ISP411_INT_SRC; 61 + 62 + isp->isp_res = kcalloc(num_res, sizeof(struct resource), 62 63 GFP_KERNEL); 63 64 if (!isp->isp_res) { 64 65 r = -ENOMEM; ··· 84 83 isp->isp_res[0].start = isp_base; 85 84 isp->isp_res[0].end = isp_base + ISP_REGS_OFFSET_END; 86 85 87 - for (int_idx = 0; int_idx < MAX_ISP411_INT_SRC; int_idx++) { 88 - isp->isp_res[int_idx + 1].name = "isp_4_1_1_irq"; 89 - isp->isp_res[int_idx + 1].flags = IORESOURCE_IRQ; 90 - isp->isp_res[int_idx + 1].start = 86 + isp->isp_res[1].name = "isp_4_1_1_phy0_reg"; 87 + isp->isp_res[1].flags = IORESOURCE_MEM; 88 + isp->isp_res[1].start = isp_base + ISP411_PHY0_OFFSET; 89 + isp->isp_res[1].end = isp_base + ISP411_PHY0_OFFSET + ISP411_PHY0_SIZE; 90 + 91 + isp->isp_res[2].name = "isp_4_1_1_sensor0_reg"; 92 + isp->isp_res[2].flags = IORESOURCE_MEM; 93 + isp->isp_res[2].start = isp_base + ISP411_GPIO_SENSOR0_OFFSET; 94 + isp->isp_res[2].end = isp_base + ISP411_GPIO_SENSOR0_OFFSET + 95 + ISP411_GPIO_SENSOR0_SIZE; 96 + 97 + for (idx = MAX_ISP411_MEM_RES + MAX_ISP411_SENSOR_RES, int_idx = 0; 98 + idx < num_res; idx++, int_idx++) { 99 + isp->isp_res[idx].name = "isp_4_1_1_irq"; 100 + isp->isp_res[idx].flags = IORESOURCE_IRQ; 101 + isp->isp_res[idx].start = 91 102 amdgpu_irq_create_mapping(adev, isp_4_1_1_int_srcid[int_idx]); 92 - isp->isp_res[int_idx + 1].end = 93 - isp->isp_res[int_idx + 1].start; 103 + isp->isp_res[idx].end = 104 + isp->isp_res[idx].start; 94 105 } 95 106 96 107 isp->isp_cell[0].name = "amd_isp_capture"; 97 - isp->isp_cell[0].num_resources = MAX_ISP411_INT_SRC + 1; 108 + isp->isp_cell[0].num_resources = num_res; 98 109 isp->isp_cell[0].resources = &isp->isp_res[0]; 99 110 isp->isp_cell[0].platform_data = isp->isp_pdata; 100 111 isp->isp_cell[0].pdata_size = sizeof(struct isp_platform_data); 101 112 102 - r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 1); 113 + isp->isp_i2c_res = kcalloc(1, sizeof(struct resource), GFP_KERNEL); 114 + if (!isp->isp_i2c_res) { 115 + r = -ENOMEM; 116 + DRM_ERROR("%s: isp mfd res alloc failed\n", __func__); 117 + goto failure; 118 + } 119 + 120 + isp->isp_i2c_res[0].name = "isp_i2c0_reg"; 121 + isp->isp_i2c_res[0].flags = IORESOURCE_MEM; 122 + isp->isp_i2c_res[0].start = isp_base + ISP411_I2C0_OFFSET; 123 + isp->isp_i2c_res[0].end = isp_base + ISP411_I2C0_OFFSET + ISP411_I2C0_SIZE; 124 + 125 + isp->isp_cell[1].name = "amd_isp_i2c_designware"; 126 + isp->isp_cell[1].num_resources = 1; 127 + isp->isp_cell[1].resources = &isp->isp_i2c_res[0]; 128 + isp->isp_cell[1].platform_data = isp->isp_pdata; 129 + isp->isp_cell[1].pdata_size = sizeof(struct isp_platform_data); 130 + 131 + r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 2); 103 132 if (r) { 104 133 DRM_ERROR("%s: add mfd hotplug device failed\n", __func__); 105 134 goto failure; ··· 142 111 kfree(isp->isp_pdata); 143 112 kfree(isp->isp_res); 144 113 kfree(isp->isp_cell); 114 + kfree(isp->isp_i2c_res); 145 115 146 116 return r; 147 117 } ··· 154 122 kfree(isp->isp_res); 155 123 kfree(isp->isp_cell); 156 124 kfree(isp->isp_pdata); 125 + kfree(isp->isp_i2c_res); 157 126 158 127 return 0; 159 128 }
+11
drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.h
··· 32 32 33 33 #include "ivsrcid/isp/irqsrcs_isp_4_1.h" 34 34 35 + #define MAX_ISP411_MEM_RES 2 36 + #define MAX_ISP411_SENSOR_RES 1 35 37 #define MAX_ISP411_INT_SRC 8 38 + 39 + #define ISP411_PHY0_OFFSET 0x66700 40 + #define ISP411_PHY0_SIZE 0xD30 41 + 42 + #define ISP411_I2C0_OFFSET 0x66400 43 + #define ISP411_I2C0_SIZE 0x100 44 + 45 + #define ISP411_GPIO_SENSOR0_OFFSET 0x6613C 46 + #define ISP411_GPIO_SENSOR0_SIZE 0x4 36 47 37 48 void isp_v4_1_1_set_isp_funcs(struct amdgpu_isp *isp); 38 49