ret = pm_runtime_get_sync(p2d->dev); if (ret < 0)
DRM_DEV_ERROR(p2d->dev, "failed to get runtime PM sync: %d\n", ret);
ret = imx_sc_misc_set_control(p2d->ipc_handle, p2d->sc_resource,
IMX_SC_C_PXL_LINK_SEL, p2d->pl_sel); if (ret)
DRM_DEV_ERROR(p2d->dev, "failed to set pixel link selection(%u): %d\n",
p2d->pl_sel, ret);
switch (p2d->out_bus_format) { case MEDIA_BUS_FMT_RGB888_1X24:
regmap_write(p2d->regmap, PXL2DPI_CTRL, CFG_24BIT); break; case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
regmap_write(p2d->regmap, PXL2DPI_CTRL, CFG2_18BIT); break; default:
DRM_DEV_ERROR(p2d->dev, "unsupported output bus format 0x%08x\n",
p2d->out_bus_format);
}
if (p2d->companion) {
companion_p2d = bridge_to_p2d(p2d->companion);
port = of_graph_get_port_by_id(p2d->dev->of_node, port_id); if (!port) {
DRM_DEV_ERROR(p2d->dev, "failed to get port@%u\n", port_id); return ERR_PTR(-ENODEV);
}
ep_cnt = of_get_available_child_count(port); if (ep_cnt == 0) {
DRM_DEV_ERROR(p2d->dev, "no available endpoints of port@%u\n",
port_id);
ep = ERR_PTR(-ENODEV); goto out;
} elseif (ep_cnt > 1) {
DRM_DEV_ERROR(p2d->dev, "invalid available endpoints of port@%u\n",
port_id);
ep = ERR_PTR(-EINVAL); goto out;
}
ep = of_get_next_available_child(port, NULL); if (!ep) {
DRM_DEV_ERROR(p2d->dev, "failed to get available endpoint of port@%u\n",
port_id);
ep = ERR_PTR(-ENODEV); goto out;
}
out:
of_node_put(port); return ep;
}
ep = imx8qxp_pxl2dpi_get_available_ep_from_port(p2d, 0); if (IS_ERR(ep)) return PTR_ERR(ep);
ret = of_graph_parse_endpoint(ep, &endpoint); if (ret) {
DRM_DEV_ERROR(p2d->dev, "failed to parse endpoint of port@0: %d\n", ret); goto out;
}
p2d->pl_sel = endpoint.id;
out:
of_node_put(ep);
return ret;
}
staticint imx8qxp_pxl2dpi_parse_dt_companion(struct imx8qxp_pxl2dpi *p2d)
{ struct imx8qxp_pxl2dpi *companion_p2d; struct device *dev = p2d->dev; struct device_node *companion; struct device_node *port1, *port2; conststruct of_device_id *match; int dual_link; int ret = 0;
/* Locate the companion PXL2DPI for dual-link operation, if any. */
companion = of_parse_phandle(dev->of_node, "fsl,companion-pxl2dpi", 0); if (!companion) return 0;
if (!of_device_is_available(companion)) {
DRM_DEV_ERROR(dev, "companion PXL2DPI is not available\n");
ret = -ENODEV; goto out;
}
/* * Sanity check: the companion bridge must have the same compatible * string.
*/
match = of_match_device(dev->driver->of_match_table, dev); if (!of_device_is_compatible(companion, match->compatible)) {
DRM_DEV_ERROR(dev, "companion PXL2DPI is incompatible\n");
ret = -ENXIO; goto out;
}
p2d->companion = of_drm_find_bridge(companion); if (!p2d->companion) {
ret = -EPROBE_DEFER;
DRM_DEV_DEBUG_DRIVER(p2d->dev, "failed to find companion bridge: %d\n",
ret); goto out;
}
companion_p2d = bridge_to_p2d(p2d->companion);
/* * We need to work out if the sink is expecting us to function in * dual-link mode. We do this by looking at the DT port nodes that * the next bridges are connected to. If they are marked as expecting * even pixels and odd pixels than we need to use the companion PXL2DPI.
*/
port1 = of_graph_get_port_by_id(p2d->next_bridge->of_node, 1);
port2 = of_graph_get_port_by_id(companion_p2d->next_bridge->of_node, 1);
dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2);
of_node_put(port1);
of_node_put(port2);
if (dual_link < 0) {
ret = dual_link;
DRM_DEV_ERROR(dev, "failed to get dual link pixel order: %d\n",
ret); goto out;
}
p2d->regmap = syscon_node_to_regmap(np->parent); if (IS_ERR(p2d->regmap)) {
ret = PTR_ERR(p2d->regmap); if (ret != -EPROBE_DEFER)
DRM_DEV_ERROR(dev, "failed to get regmap: %d\n", ret); return ret;
}
ret = imx_scu_get_handle(&p2d->ipc_handle); if (ret) { if (ret != -EPROBE_DEFER)
DRM_DEV_ERROR(dev, "failed to get SCU ipc handle: %d\n",
ret); return ret;
}
p2d->dev = dev;
ret = of_property_read_u32(np, "fsl,sc-resource", &p2d->sc_resource); if (ret) {
DRM_DEV_ERROR(dev, "failed to get SC resource %d\n", ret); return ret;
}
p2d->next_bridge = imx8qxp_pxl2dpi_find_next_bridge(p2d); if (IS_ERR(p2d->next_bridge)) {
ret = PTR_ERR(p2d->next_bridge); if (ret != -EPROBE_DEFER)
DRM_DEV_ERROR(dev, "failed to find next bridge: %d\n",
ret); return ret;
}
ret = imx8qxp_pxl2dpi_set_pixel_link_sel(p2d); if (ret) return ret;
ret = imx8qxp_pxl2dpi_parse_dt_companion(p2d); if (ret) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.