On Thu, Jul 11, 2024 at 7:40 PM Venkata Narendra Kumar Gutta <vengutta@xxxxxxx> wrote: > > 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@xxxxxxx> Ackd-by: Alex Deucher <alexander.deucher@xxxxxxx> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_isp.h | 1 + > drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c | 57 +++++++++++++++++++------ > drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.h | 12 ++++++ > drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c | 57 +++++++++++++++++++------ > drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.h | 11 +++++ > 5 files changed, 114 insertions(+), 24 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_isp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_isp.h > index 44e2ea8c9728..b03664c66dd6 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_isp.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_isp.h > @@ -49,6 +49,7 @@ struct amdgpu_isp { > const struct isp_funcs *funcs; > struct mfd_cell *isp_cell; > struct resource *isp_res; > + struct resource *isp_i2c_res; > struct isp_platform_data *isp_pdata; > unsigned int harvest_config; > const struct firmware *fw; > diff --git a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c > index aac107898bae..964c29ef25dc 100644 > --- a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c > @@ -42,23 +42,23 @@ static const unsigned int isp_4_1_0_int_srcid[MAX_ISP410_INT_SRC] = { > static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) > { > struct amdgpu_device *adev = isp->adev; > + int idx, int_idx, num_res, r; > u64 isp_base; > - int int_idx; > - int r; > > if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289) > return -EINVAL; > > isp_base = adev->rmmio_base; > > - isp->isp_cell = kcalloc(1, sizeof(struct mfd_cell), GFP_KERNEL); > + isp->isp_cell = kcalloc(2, sizeof(struct mfd_cell), GFP_KERNEL); > if (!isp->isp_cell) { > r = -ENOMEM; > DRM_ERROR("%s: isp mfd cell alloc failed\n", __func__); > goto failure; > } > > - isp->isp_res = kcalloc(MAX_ISP410_INT_SRC + 1, sizeof(struct resource), > + num_res = MAX_ISP410_MEM_RES + MAX_ISP410_SENSOR_RES + MAX_ISP410_INT_SRC; > + isp->isp_res = kcalloc(num_res, sizeof(struct resource), > GFP_KERNEL); > if (!isp->isp_res) { > r = -ENOMEM; > @@ -83,22 +83,53 @@ static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) > isp->isp_res[0].start = isp_base; > isp->isp_res[0].end = isp_base + ISP_REGS_OFFSET_END; > > - for (int_idx = 0; int_idx < MAX_ISP410_INT_SRC; int_idx++) { > - isp->isp_res[int_idx + 1].name = "isp_4_1_0_irq"; > - isp->isp_res[int_idx + 1].flags = IORESOURCE_IRQ; > - isp->isp_res[int_idx + 1].start = > + isp->isp_res[1].name = "isp_4_1_phy0_reg"; > + isp->isp_res[1].flags = IORESOURCE_MEM; > + isp->isp_res[1].start = isp_base + ISP410_PHY0_OFFSET; > + isp->isp_res[1].end = isp_base + ISP410_PHY0_OFFSET + ISP410_PHY0_SIZE; > + > + isp->isp_res[2].name = "isp_gpio_sensor0_reg"; > + isp->isp_res[2].flags = IORESOURCE_MEM; > + isp->isp_res[2].start = isp_base + ISP410_GPIO_SENSOR0_OFFSET; > + isp->isp_res[2].end = isp_base + ISP410_GPIO_SENSOR0_OFFSET + > + ISP410_GPIO_SENSOR0_SIZE; > + > + for (idx = MAX_ISP410_MEM_RES + MAX_ISP410_SENSOR_RES, int_idx = 0; > + idx < num_res; idx++, int_idx++) { > + isp->isp_res[idx].name = "isp_4_1_0_irq"; > + isp->isp_res[idx].flags = IORESOURCE_IRQ; > + isp->isp_res[idx].start = > amdgpu_irq_create_mapping(adev, isp_4_1_0_int_srcid[int_idx]); > - isp->isp_res[int_idx + 1].end = > - isp->isp_res[int_idx + 1].start; > + isp->isp_res[idx].end = > + isp->isp_res[idx].start; > } > > isp->isp_cell[0].name = "amd_isp_capture"; > - isp->isp_cell[0].num_resources = MAX_ISP410_INT_SRC + 1; > + isp->isp_cell[0].num_resources = num_res; > isp->isp_cell[0].resources = &isp->isp_res[0]; > isp->isp_cell[0].platform_data = isp->isp_pdata; > isp->isp_cell[0].pdata_size = sizeof(struct isp_platform_data); > > - r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 1); > + isp->isp_i2c_res = kcalloc(1, sizeof(struct resource), > + GFP_KERNEL); > + if (!isp->isp_i2c_res) { > + r = -ENOMEM; > + DRM_ERROR("%s: isp mfd res alloc failed\n", __func__); > + goto failure; > + } > + > + isp->isp_i2c_res[0].name = "isp_i2c0_reg"; > + isp->isp_i2c_res[0].flags = IORESOURCE_MEM; > + isp->isp_i2c_res[0].start = isp_base + ISP410_I2C0_OFFSET; > + isp->isp_i2c_res[0].end = isp_base + ISP410_I2C0_OFFSET + ISP410_I2C0_SIZE; > + > + isp->isp_cell[1].name = "amd_isp_i2c_designware"; > + isp->isp_cell[1].num_resources = 1; > + isp->isp_cell[1].resources = &isp->isp_i2c_res[0]; > + isp->isp_cell[1].platform_data = isp->isp_pdata; > + isp->isp_cell[1].pdata_size = sizeof(struct isp_platform_data); > + > + r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 2); > if (r) { > DRM_ERROR("%s: add mfd hotplug device failed\n", __func__); > goto failure; > @@ -111,6 +142,7 @@ static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) > kfree(isp->isp_pdata); > kfree(isp->isp_res); > kfree(isp->isp_cell); > + kfree(isp->isp_i2c_res); > > return r; > } > @@ -122,6 +154,7 @@ static int isp_v4_1_0_hw_fini(struct amdgpu_isp *isp) > kfree(isp->isp_res); > kfree(isp->isp_cell); > kfree(isp->isp_pdata); > + kfree(isp->isp_i2c_res); > > return 0; > } > diff --git a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.h b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.h > index 315f2822410c..d6f7ffb0e2f7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.h > +++ b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.h > @@ -32,8 +32,20 @@ > > #include "ivsrcid/isp/irqsrcs_isp_4_1.h" > > +#define MAX_ISP410_MEM_RES 2 > +#define MAX_ISP410_SENSOR_RES 1 > #define MAX_ISP410_INT_SRC 8 > > +#define ISP410_PHY0_OFFSET 0x66700 > +#define ISP410_PHY0_SIZE 0xD30 > + > +#define ISP410_I2C0_OFFSET 0x66400 > +#define ISP410_I2C0_SIZE 0x100 > + > +#define ISP410_GPIO_SENSOR0_OFFSET 0x6613C > +#define ISP410_GPIO_SENSOR0_SIZE 0x4 > + > + > void isp_v4_1_0_set_isp_funcs(struct amdgpu_isp *isp); > > #endif > diff --git a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c > index 4e17fa03f7b5..b56f27295468 100644 > --- a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c > +++ b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c > @@ -42,23 +42,24 @@ static const unsigned int isp_4_1_1_int_srcid[MAX_ISP411_INT_SRC] = { > static int isp_v4_1_1_hw_init(struct amdgpu_isp *isp) > { > struct amdgpu_device *adev = isp->adev; > + int idx, int_idx, num_res, r; > u64 isp_base; > - int int_idx; > - int r; > > if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289) > return -EINVAL; > > isp_base = adev->rmmio_base; > > - isp->isp_cell = kcalloc(1, sizeof(struct mfd_cell), GFP_KERNEL); > + isp->isp_cell = kcalloc(2, sizeof(struct mfd_cell), GFP_KERNEL); > if (!isp->isp_cell) { > r = -ENOMEM; > DRM_ERROR("%s: isp mfd cell alloc failed\n", __func__); > goto failure; > } > > - isp->isp_res = kcalloc(MAX_ISP411_INT_SRC + 1, sizeof(struct resource), > + num_res = MAX_ISP411_MEM_RES + MAX_ISP411_SENSOR_RES + MAX_ISP411_INT_SRC; > + > + isp->isp_res = kcalloc(num_res, sizeof(struct resource), > GFP_KERNEL); > if (!isp->isp_res) { > r = -ENOMEM; > @@ -83,22 +84,52 @@ static int isp_v4_1_1_hw_init(struct amdgpu_isp *isp) > isp->isp_res[0].start = isp_base; > isp->isp_res[0].end = isp_base + ISP_REGS_OFFSET_END; > > - for (int_idx = 0; int_idx < MAX_ISP411_INT_SRC; int_idx++) { > - isp->isp_res[int_idx + 1].name = "isp_4_1_1_irq"; > - isp->isp_res[int_idx + 1].flags = IORESOURCE_IRQ; > - isp->isp_res[int_idx + 1].start = > + isp->isp_res[1].name = "isp_4_1_1_phy0_reg"; > + isp->isp_res[1].flags = IORESOURCE_MEM; > + isp->isp_res[1].start = isp_base + ISP411_PHY0_OFFSET; > + isp->isp_res[1].end = isp_base + ISP411_PHY0_OFFSET + ISP411_PHY0_SIZE; > + > + isp->isp_res[2].name = "isp_4_1_1_sensor0_reg"; > + isp->isp_res[2].flags = IORESOURCE_MEM; > + isp->isp_res[2].start = isp_base + ISP411_GPIO_SENSOR0_OFFSET; > + isp->isp_res[2].end = isp_base + ISP411_GPIO_SENSOR0_OFFSET + > + ISP411_GPIO_SENSOR0_SIZE; > + > + for (idx = MAX_ISP411_MEM_RES + MAX_ISP411_SENSOR_RES, int_idx = 0; > + idx < num_res; idx++, int_idx++) { > + isp->isp_res[idx].name = "isp_4_1_1_irq"; > + isp->isp_res[idx].flags = IORESOURCE_IRQ; > + isp->isp_res[idx].start = > amdgpu_irq_create_mapping(adev, isp_4_1_1_int_srcid[int_idx]); > - isp->isp_res[int_idx + 1].end = > - isp->isp_res[int_idx + 1].start; > + isp->isp_res[idx].end = > + isp->isp_res[idx].start; > } > > isp->isp_cell[0].name = "amd_isp_capture"; > - isp->isp_cell[0].num_resources = MAX_ISP411_INT_SRC + 1; > + isp->isp_cell[0].num_resources = num_res; > isp->isp_cell[0].resources = &isp->isp_res[0]; > isp->isp_cell[0].platform_data = isp->isp_pdata; > isp->isp_cell[0].pdata_size = sizeof(struct isp_platform_data); > > - r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 1); > + isp->isp_i2c_res = kcalloc(1, sizeof(struct resource), GFP_KERNEL); > + if (!isp->isp_i2c_res) { > + r = -ENOMEM; > + DRM_ERROR("%s: isp mfd res alloc failed\n", __func__); > + goto failure; > + } > + > + isp->isp_i2c_res[0].name = "isp_i2c0_reg"; > + isp->isp_i2c_res[0].flags = IORESOURCE_MEM; > + isp->isp_i2c_res[0].start = isp_base + ISP411_I2C0_OFFSET; > + isp->isp_i2c_res[0].end = isp_base + ISP411_I2C0_OFFSET + ISP411_I2C0_SIZE; > + > + isp->isp_cell[1].name = "amd_isp_i2c_designware"; > + isp->isp_cell[1].num_resources = 1; > + isp->isp_cell[1].resources = &isp->isp_i2c_res[0]; > + isp->isp_cell[1].platform_data = isp->isp_pdata; > + isp->isp_cell[1].pdata_size = sizeof(struct isp_platform_data); > + > + r = mfd_add_hotplug_devices(isp->parent, isp->isp_cell, 2); > if (r) { > DRM_ERROR("%s: add mfd hotplug device failed\n", __func__); > goto failure; > @@ -111,6 +142,7 @@ static int isp_v4_1_1_hw_init(struct amdgpu_isp *isp) > kfree(isp->isp_pdata); > kfree(isp->isp_res); > kfree(isp->isp_cell); > + kfree(isp->isp_i2c_res); > > return r; > } > @@ -122,6 +154,7 @@ static int isp_v4_1_1_hw_fini(struct amdgpu_isp *isp) > kfree(isp->isp_res); > kfree(isp->isp_cell); > kfree(isp->isp_pdata); > + kfree(isp->isp_i2c_res); > > return 0; > } > diff --git a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.h b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.h > index dfb9522c9d6a..40887ddeb08c 100644 > --- a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.h > +++ b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.h > @@ -32,8 +32,19 @@ > > #include "ivsrcid/isp/irqsrcs_isp_4_1.h" > > +#define MAX_ISP411_MEM_RES 2 > +#define MAX_ISP411_SENSOR_RES 1 > #define MAX_ISP411_INT_SRC 8 > > +#define ISP411_PHY0_OFFSET 0x66700 > +#define ISP411_PHY0_SIZE 0xD30 > + > +#define ISP411_I2C0_OFFSET 0x66400 > +#define ISP411_I2C0_SIZE 0x100 > + > +#define ISP411_GPIO_SENSOR0_OFFSET 0x6613C > +#define ISP411_GPIO_SENSOR0_SIZE 0x4 > + > void isp_v4_1_1_set_isp_funcs(struct amdgpu_isp *isp); > > #endif > -- > 2.34.1 >