Commit 25dd25f8 authored by Venkata Narendra Kumar Gutta's avatar Venkata Narendra Kumar Gutta Committed by Alex Deucher

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: default avatarVenkata Narendra Kumar Gutta <vengutta@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent fbfb5f03
......@@ -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;
......
......@@ -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;
}
......
......@@ -32,8 +32,19 @@
#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
......@@ -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;
}
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment