@@ -1016,23 +1016,15 @@ static const struct of_device_id mdp_comp_dt_ids[] = {
{}
};
-static int mdp_comp_get_id(struct device *dev, struct device_node *node,
- enum mdp_comp_type type)
+static int mdp_comp_get_id(enum mdp_comp_type type, u32 alias_id)
{
- u32 alias_id;
- int i, ret;
-
- ret = of_property_read_u32(node, "mediatek,mdp-id", &alias_id);
- if (ret)
- return ret;
+ int i;
for (i = 0; i < ARRAY_SIZE(mdp_comp_matches); i++)
if (mdp_comp_matches[i].type == type &&
mdp_comp_matches[i].alias_id == alias_id)
return i;
-
- dev_err(dev, "Failed to get id. type: %d, alias: %d\n", type, alias_id);
- return -EINVAL;
+ return -ENODEV;
}
void mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
@@ -1143,33 +1135,10 @@ static void __mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
comp->reg_base = base;
}
-static int mdp_mm_init(struct mdp_dev *mdp,
- struct mdp_comp *comp, const char *ref_name)
+static int mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
+ struct mdp_comp *comp, enum mdp_comp_id id)
{
- struct device_node *node;
struct device *dev = &mdp->pdev->dev;
-
- node = of_parse_phandle(dev->of_node, ref_name, 0);
- if (!node) {
- dev_err(dev, "Failed to parse dt %s\n", ref_name);
- return -EINVAL;
- }
-
- __mdp_comp_init(mdp, node, comp);
- mdp_get_subsys_id(dev, node, comp);
- of_node_put(node);
- if (!comp->reg_base) {
- dev_err(dev, "Failed to init %s base\n", ref_name);
- return -EINVAL;
- }
- return 0;
-}
-
-static int mdp_comp_init(struct device *dev, struct mdp_dev *mdp,
- struct device_node *node, struct mdp_comp *comp,
- enum mdp_comp_id id)
-{
- struct platform_device *pdev;
int i;
if (id < 0 || id >= MDP_MAX_COMP_COUNT) {
@@ -1191,32 +1160,140 @@ static int mdp_comp_init(struct device *dev, struct mdp_dev *mdp,
mdp_get_subsys_id(dev, node, comp);
- /* Only DMA capable components need the pm control */
- comp->comp_dev = NULL;
- if (comp->type != MDP_COMP_TYPE_RDMA &&
- comp->type != MDP_COMP_TYPE_WROT &&
- comp->type != MDP_COMP_TYPE_WDMA)
- return 0;
+ return 0;
+}
- pdev = of_find_device_by_node(node);
- if (!pdev) {
- dev_warn(dev, "can't find platform device of node:%s\n",
- node->name);
- return -ENODEV;
+static struct mdp_comp *mdp_comp_create(struct mdp_dev *mdp,
+ struct device_node *node,
+ enum mdp_comp_id id)
+{
+ struct device *dev = &mdp->pdev->dev;
+ struct mdp_comp *comp;
+ int ret;
+
+ if (mdp->comp[id])
+ return ERR_PTR(-EEXIST);
+
+ comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
+ if (!comp)
+ return ERR_PTR(-ENOMEM);
+
+ ret = mdp_comp_init(mdp, node, comp, id);
+ if (ret) {
+ kfree(comp);
+ return ERR_PTR(ret);
}
+ mdp->comp[id] = comp;
+
+ dev_info(dev, "%s type:%d alias:%d id:%d base:%#x regs:%p\n",
+ dev->of_node->name, comp->type, comp->alias_id, id,
+ (u32)comp->reg_base, comp->regs);
+ return comp;
+}
- comp->comp_dev = &pdev->dev;
- pm_runtime_enable(comp->comp_dev);
+static int mdp_sub_comps_create(struct mdp_dev *mdp, struct device_node *node)
+{
+ struct device *dev = &mdp->pdev->dev;
+ struct property *prop;
+ const char *name;
+ int index = 0;
+
+ of_property_for_each_string(node, "mdp-comps", prop, name) {
+ const struct of_device_id *matches = mdp_comp_dt_ids;
+ enum mdp_comp_type type = MDP_COMP_NONE;
+ u32 alias_id;
+ int id, ret;
+ struct mdp_comp *comp;
+ for (; matches->compatible[0]; matches++) {
+ if (of_compat_cmp(name, matches->compatible,
+ strlen(matches->compatible)) == 0) {
+ type = (enum mdp_comp_type)matches->data;
+ break;
+ }
+ }
+
+ ret = of_property_read_u32_index(node, "mdp-comp-ids",
+ index, &alias_id);
+ if (ret) {
+ dev_warn(dev, "Skipping unknown component %s\n", name);
+ return ret;
+ }
+
+ id = mdp_comp_get_id(type, alias_id);
+ if (id < 0) {
+ dev_err(dev, "Failed to get component id: "
+ "%s type %d, alias %d\n", name, type, alias_id);
+ return -ENODEV;
+ }
+
+ comp = mdp_comp_create(mdp, node, id);
+ if (IS_ERR(comp))
+ return PTR_ERR(comp);
+
+ index++;
+ }
return 0;
}
static void mdp_comp_deinit(struct mdp_comp *comp)
{
- iounmap(comp->regs);
+ if (!comp)
+ return;
+
+ if (comp->regs)
+ iounmap(comp->regs);
/* of_node_put(comp->dev_node); */
}
+static int mdp_imgi_init(struct mdp_dev *mdp, const char *ref_name)
+{
+ struct device_node *node;
+ struct device *dev = &mdp->pdev->dev;
+ int ret;
+
+ node = of_parse_phandle(dev->of_node, ref_name, 0);
+ if (!node) {
+ dev_err(dev, "Failed to parse dt %s\n", ref_name);
+ return -EINVAL;
+ }
+
+ ret = mdp_sub_comps_create(mdp, node);
+ of_node_put(node);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int mdp_mm_init(struct mdp_dev *mdp, struct mdp_comp *comp,
+ const char *ref_name)
+{
+ struct device_node *node;
+ struct device *dev = &mdp->pdev->dev;
+ int ret;
+
+ node = of_parse_phandle(dev->of_node, ref_name, 0);
+ if (!node) {
+ dev_err(dev, "Failed to parse dt %s\n", ref_name);
+ return -EINVAL;
+ }
+
+ __mdp_comp_init(mdp, node, comp);
+ mdp_get_subsys_id(dev, node, comp);
+ if (!comp->reg_base) {
+ dev_err(dev, "Failed to init %s base\n", ref_name);
+ of_node_put(node);
+ return -EINVAL;
+ }
+
+ ret = mdp_sub_comps_create(mdp, node);
+ of_node_put(node);
+ if (ret)
+ return ret;
+ return 0;
+}
+
void mdp_component_deinit(struct mdp_dev *mdp)
{
int i;
@@ -1235,6 +1312,8 @@ int mdp_component_init(struct mdp_dev *mdp)
{
struct device *dev = &mdp->pdev->dev;
struct device_node *node, *parent;
+ struct platform_device *pdev;
+ u32 alias_id;
int i, ret;
for (i = RDMA0_SOF; i < MDP_MAX_EVENT_COUNT; i++) {
@@ -1260,7 +1339,11 @@ int mdp_component_init(struct mdp_dev *mdp)
ret = mdp_mm_init(mdp, &mdp->mm_mutex, "mediatek,mm-mutex");
if (ret)
- goto err_init_mm;
+ goto err_init_comps;
+
+ ret = mdp_imgi_init(mdp, "mediatek,imgsys");
+ if (ret)
+ goto err_init_comps;
parent = dev->of_node->parent;
/* Iterate over sibling MDP function blocks */
@@ -1281,27 +1364,44 @@ int mdp_component_init(struct mdp_dev *mdp)
}
type = (enum mdp_comp_type)of_id->data;
- id = mdp_comp_get_id(dev, node, type);
- if (id < 0) {
+ ret = of_property_read_u32(node, "mediatek,mdp-id", &alias_id);
+ if (ret) {
dev_warn(dev, "Skipping unknown component %pOF\n",
node);
continue;
}
+ id = mdp_comp_get_id(type, alias_id);
+ if (id < 0) {
+ dev_err(dev,
+ "Fail to get component id: type %d alias %d\n",
+ type, alias_id);
+ continue;
+ }
- comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
- if (!comp) {
- ret = -ENOMEM;
+ comp = mdp_comp_create(mdp, node, id);
+ if (IS_ERR(comp))
goto err_init_comps;
- }
- mdp->comp[id] = comp;
- ret = mdp_comp_init(dev, mdp, node, comp, id);
+ ret = mdp_sub_comps_create(mdp, node);
if (ret)
goto err_init_comps;
- dev_info(dev, "%s type:%d alias:%d id:%d base:%#x regs:%p\n",
- of_id->compatible, type, comp->alias_id, id,
- (u32)comp->reg_base, comp->regs);
+ /* Only DMA capable components need the pm control */
+ comp->comp_dev = NULL;
+ if (comp->type != MDP_COMP_TYPE_RDMA &&
+ comp->type != MDP_COMP_TYPE_WROT &&
+ comp->type != MDP_COMP_TYPE_WDMA)
+ continue;
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev) {
+ dev_warn(dev, "can't find platform device of node:%s\n",
+ node->name);
+ return -ENODEV;
+ }
+
+ comp->comp_dev = &pdev->dev;
+ pm_runtime_enable(comp->comp_dev);
}
return 0;
@@ -112,7 +112,7 @@ struct mdp_comp {
void __iomem *regs;
phys_addr_t reg_base;
u8 subsys_id;
- struct clk *clks[2];
+ struct clk *clks[4];
struct device *comp_dev;
enum mdp_comp_type type;
enum mdp_comp_id id;
This patch is used for review before send upstream patch. From Rob Herring's review comment: device node can't use same register address as other nodes'. Remove illegal device nodes in device tree. MDP's sub component init need to do corresponding modification. Signed-off-by: Moudy Ho <moudy.ho@mediatek.com> --- .../media/platform/mtk-mdp3/mtk-mdp3-comp.c | 224 +++++++++++++----- .../media/platform/mtk-mdp3/mtk-mdp3-comp.h | 2 +- 2 files changed, 163 insertions(+), 63 deletions(-)