drm/komeda: Update the chip identify

1. Drop komeda-CORE product id comparison and put it into the d71_identify
2. Update pipeline node DT-binding:
   (a). Skip the needless pipeline DT node.
   (b). Return fail if the essential pipeline DT node is missing.

With these changes, for chips in same family no need to change the DT.

v2: Rebase
v3: Address Mihail's comments.
Signed-off-by: default avatarjames qian wang (Arm Technology China) <james.qian.wang@arm.com>
Reviewed-by: default avatarMihail Atanassov <mihail.atanassov@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191210084828.19664-2-james.qian.wang@arm.com
parent 6fd70eab
...@@ -597,10 +597,25 @@ static const struct komeda_dev_funcs d71_chip_funcs = { ...@@ -597,10 +597,25 @@ static const struct komeda_dev_funcs d71_chip_funcs = {
const struct komeda_dev_funcs * const struct komeda_dev_funcs *
d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip) d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip)
{ {
const struct komeda_dev_funcs *funcs;
u32 product_id;
chip->core_id = malidp_read32(reg_base, GLB_CORE_ID);
product_id = MALIDP_CORE_ID_PRODUCT_ID(chip->core_id);
switch (product_id) {
case MALIDP_D71_PRODUCT_ID:
funcs = &d71_chip_funcs;
break;
default:
DRM_ERROR("Unsupported product: 0x%x\n", product_id);
return NULL;
}
chip->arch_id = malidp_read32(reg_base, GLB_ARCH_ID); chip->arch_id = malidp_read32(reg_base, GLB_ARCH_ID);
chip->core_id = malidp_read32(reg_base, GLB_CORE_ID);
chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO); chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO);
chip->bus_width = D71_BUS_WIDTH_16_BYTES; chip->bus_width = D71_BUS_WIDTH_16_BYTES;
return &d71_chip_funcs; return funcs;
} }
...@@ -115,22 +115,14 @@ static struct attribute_group komeda_sysfs_attr_group = { ...@@ -115,22 +115,14 @@ static struct attribute_group komeda_sysfs_attr_group = {
.attrs = komeda_sysfs_entries, .attrs = komeda_sysfs_entries,
}; };
static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node *np) static int komeda_parse_pipe_dt(struct komeda_pipeline *pipe)
{ {
struct komeda_pipeline *pipe; struct device_node *np = pipe->of_node;
struct clk *clk; struct clk *clk;
u32 pipe_id;
int ret = 0;
ret = of_property_read_u32(np, "reg", &pipe_id);
if (ret != 0 || pipe_id >= mdev->n_pipelines)
return -EINVAL;
pipe = mdev->pipelines[pipe_id];
clk = of_clk_get_by_name(np, "pxclk"); clk = of_clk_get_by_name(np, "pxclk");
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
DRM_ERROR("get pxclk for pipeline %d failed!\n", pipe_id); DRM_ERROR("get pxclk for pipeline %d failed!\n", pipe->id);
return PTR_ERR(clk); return PTR_ERR(clk);
} }
pipe->pxlclk = clk; pipe->pxlclk = clk;
...@@ -144,7 +136,6 @@ static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node *np) ...@@ -144,7 +136,6 @@ static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node *np)
of_graph_get_port_by_id(np, KOMEDA_OF_PORT_OUTPUT); of_graph_get_port_by_id(np, KOMEDA_OF_PORT_OUTPUT);
pipe->dual_link = pipe->of_output_links[0] && pipe->of_output_links[1]; pipe->dual_link = pipe->of_output_links[0] && pipe->of_output_links[1];
pipe->of_node = of_node_get(np);
return 0; return 0;
} }
...@@ -153,7 +144,9 @@ static int komeda_parse_dt(struct device *dev, struct komeda_dev *mdev) ...@@ -153,7 +144,9 @@ static int komeda_parse_dt(struct device *dev, struct komeda_dev *mdev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
struct device_node *child, *np = dev->of_node; struct device_node *child, *np = dev->of_node;
int ret; struct komeda_pipeline *pipe;
u32 pipe_id = U32_MAX;
int ret = -1;
mdev->irq = platform_get_irq(pdev, 0); mdev->irq = platform_get_irq(pdev, 0);
if (mdev->irq < 0) { if (mdev->irq < 0) {
...@@ -168,28 +161,42 @@ static int komeda_parse_dt(struct device *dev, struct komeda_dev *mdev) ...@@ -168,28 +161,42 @@ static int komeda_parse_dt(struct device *dev, struct komeda_dev *mdev)
ret = 0; ret = 0;
for_each_available_child_of_node(np, child) { for_each_available_child_of_node(np, child) {
if (of_node_cmp(child->name, "pipeline") == 0) { if (of_node_name_eq(child, "pipeline")) {
ret = komeda_parse_pipe_dt(mdev, child); of_property_read_u32(child, "reg", &pipe_id);
if (ret) { if (pipe_id >= mdev->n_pipelines) {
DRM_ERROR("parse pipeline dt error!\n"); DRM_WARN("Skip the redundant DT node: pipeline-%u.\n",
of_node_put(child); pipe_id);
break; continue;
} }
mdev->pipelines[pipe_id]->of_node = of_node_get(child);
} }
} }
return ret; for (pipe_id = 0; pipe_id < mdev->n_pipelines; pipe_id++) {
pipe = mdev->pipelines[pipe_id];
if (!pipe->of_node) {
DRM_ERROR("Pipeline-%d doesn't have a DT node.\n",
pipe->id);
return -EINVAL;
}
ret = komeda_parse_pipe_dt(pipe);
if (ret)
return ret;
}
return 0;
} }
struct komeda_dev *komeda_dev_create(struct device *dev) struct komeda_dev *komeda_dev_create(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
const struct komeda_product_data *product; komeda_identify_func komeda_identify;
struct komeda_dev *mdev; struct komeda_dev *mdev;
int err = 0; int err = 0;
product = of_device_get_match_data(dev); komeda_identify = of_device_get_match_data(dev);
if (!product) if (!komeda_identify)
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
mdev = devm_kzalloc(dev, sizeof(*mdev), GFP_KERNEL); mdev = devm_kzalloc(dev, sizeof(*mdev), GFP_KERNEL);
...@@ -217,11 +224,9 @@ struct komeda_dev *komeda_dev_create(struct device *dev) ...@@ -217,11 +224,9 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
clk_prepare_enable(mdev->aclk); clk_prepare_enable(mdev->aclk);
mdev->funcs = product->identify(mdev->reg_base, &mdev->chip); mdev->funcs = komeda_identify(mdev->reg_base, &mdev->chip);
if (!komeda_product_match(mdev, product->product_id)) { if (!mdev->funcs) {
DRM_ERROR("DT configured %x mismatch with real HW %x.\n", DRM_ERROR("Failed to identify the HW.\n");
product->product_id,
MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id));
err = -ENODEV; err = -ENODEV;
goto disable_clk; goto disable_clk;
} }
......
...@@ -58,11 +58,6 @@ ...@@ -58,11 +58,6 @@
| KOMEDA_EVENT_MODE \ | KOMEDA_EVENT_MODE \
) )
/* malidp device id */
enum {
MALI_D71 = 0,
};
/* pipeline DT ports */ /* pipeline DT ports */
enum { enum {
KOMEDA_OF_PORT_OUTPUT = 0, KOMEDA_OF_PORT_OUTPUT = 0,
...@@ -76,12 +71,6 @@ struct komeda_chip_info { ...@@ -76,12 +71,6 @@ struct komeda_chip_info {
u32 bus_width; u32 bus_width;
}; };
struct komeda_product_data {
u32 product_id;
const struct komeda_dev_funcs *(*identify)(u32 __iomem *reg,
struct komeda_chip_info *info);
};
struct komeda_dev; struct komeda_dev;
struct komeda_events { struct komeda_events {
...@@ -234,6 +223,9 @@ komeda_product_match(struct komeda_dev *mdev, u32 target) ...@@ -234,6 +223,9 @@ komeda_product_match(struct komeda_dev *mdev, u32 target)
return MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id) == target; return MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id) == target;
} }
typedef const struct komeda_dev_funcs *
(*komeda_identify_func)(u32 __iomem *reg, struct komeda_chip_info *chip);
const struct komeda_dev_funcs * const struct komeda_dev_funcs *
d71_identify(u32 __iomem *reg, struct komeda_chip_info *chip); d71_identify(u32 __iomem *reg, struct komeda_chip_info *chip);
......
...@@ -123,15 +123,8 @@ static int komeda_platform_remove(struct platform_device *pdev) ...@@ -123,15 +123,8 @@ static int komeda_platform_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct komeda_product_data komeda_products[] = {
[MALI_D71] = {
.product_id = MALIDP_D71_PRODUCT_ID,
.identify = d71_identify,
},
};
static const struct of_device_id komeda_of_match[] = { static const struct of_device_id komeda_of_match[] = {
{ .compatible = "arm,mali-d71", .data = &komeda_products[MALI_D71], }, { .compatible = "arm,mali-d71", .data = d71_identify, },
{}, {},
}; };
......
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