/* LCDC DRM driver, based on da8xx-fb */
-#include <linux/component.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
platform_set_drvdata(pdev, ddev);
drm_mode_config_init(ddev);
- priv->is_componentized =
- tilcdc_get_external_components(dev, NULL) > 0;
-
priv->wq = alloc_ordered_workqueue("tilcdc", 0);
if (!priv->wq) {
ret = -ENOMEM;
}
#endif
- if (priv->is_componentized) {
- ret = component_bind_all(dev, ddev);
- if (ret < 0)
- goto unregister_cpufreq_notif;
-
- ret = tilcdc_add_component_encoder(ddev);
- if (ret < 0)
- goto unbind_component;
- } else {
- ret = tilcdc_attach_external_device(ddev);
- if (ret)
- goto unregister_cpufreq_notif;
- }
+ ret = tilcdc_attach_external_device(ddev);
+ if (ret)
+ goto unregister_cpufreq_notif;
if (!priv->external_connector &&
((priv->num_encoders == 0) || (priv->num_connectors == 0))) {
dev_err(dev, "no encoders/connectors found\n");
ret = -EPROBE_DEFER;
- goto unbind_component;
+ goto unregister_cpufreq_notif;
}
ret = drm_vblank_init(ddev, 1);
if (ret < 0) {
dev_err(dev, "failed to initialize vblank\n");
- goto unbind_component;
+ goto unregister_cpufreq_notif;
}
ret = platform_get_irq(pdev, 0);
if (ret < 0)
- goto unbind_component;
+ goto unregister_cpufreq_notif;
priv->irq = ret;
ret = tilcdc_irq_install(ddev, priv->irq);
if (ret < 0) {
dev_err(dev, "failed to install IRQ handler\n");
- goto unbind_component;
+ goto unregister_cpufreq_notif;
}
drm_mode_config_reset(ddev);
stop_poll:
drm_kms_helper_poll_fini(ddev);
tilcdc_irq_uninstall(ddev);
-unbind_component:
- if (priv->is_componentized)
- component_unbind_all(dev, ddev);
unregister_cpufreq_notif:
#ifdef CONFIG_CPU_FREQ
cpufreq_unregister_notifier(&priv->freq_transition,
static DEFINE_SIMPLE_DEV_PM_OPS(tilcdc_pm_ops,
tilcdc_pm_suspend, tilcdc_pm_resume);
-/*
- * Platform driver:
- */
-static int tilcdc_bind(struct device *dev)
-{
- return tilcdc_init(&tilcdc_driver, dev);
-}
-
-static void tilcdc_unbind(struct device *dev)
-{
- struct drm_device *ddev = dev_get_drvdata(dev);
-
- /* Check if a subcomponent has already triggered the unloading. */
- if (!ddev->dev_private)
- return;
-
- tilcdc_fini(ddev);
- dev_set_drvdata(dev, NULL);
-}
-
-static const struct component_master_ops tilcdc_comp_ops = {
- .bind = tilcdc_bind,
- .unbind = tilcdc_unbind,
-};
-
static int tilcdc_pdev_probe(struct platform_device *pdev)
{
- struct component_match *match = NULL;
- int ret;
-
/* bail out early if no DT data: */
if (!pdev->dev.of_node) {
dev_err(&pdev->dev, "device-tree data is missing\n");
return -ENXIO;
}
- ret = tilcdc_get_external_components(&pdev->dev, &match);
- if (ret < 0)
- return ret;
- else if (ret == 0)
- return tilcdc_init(&tilcdc_driver, &pdev->dev);
- else
- return component_master_add_with_match(&pdev->dev,
- &tilcdc_comp_ops,
- match);
+ return tilcdc_init(&tilcdc_driver, &pdev->dev);
}
static void tilcdc_pdev_remove(struct platform_device *pdev)
{
- int ret;
-
- ret = tilcdc_get_external_components(&pdev->dev, NULL);
- if (ret < 0)
- dev_err(&pdev->dev, "tilcdc_get_external_components() failed (%pe)\n",
- ERR_PTR(ret));
- else if (ret == 0)
- tilcdc_fini(platform_get_drvdata(pdev));
- else
- component_master_del(&pdev->dev, &tilcdc_comp_ops);
+ tilcdc_fini(platform_get_drvdata(pdev));
}
static void tilcdc_pdev_shutdown(struct platform_device *pdev)
* Author: Jyri Sarha <jsarha@ti.com>
*/
-#include <linux/component.h>
#include <linux/of_graph.h>
#include <drm/drm_atomic_helper.h>
#include "tilcdc_drv.h"
#include "tilcdc_external.h"
-static const struct tilcdc_panel_info panel_info_tda998x = {
- .ac_bias = 255,
- .ac_bias_intrpt = 0,
- .dma_burst_sz = 16,
- .bpp = 16,
- .fdd = 0x80,
- .tft_alt_mode = 0,
- .invert_pxl_clk = 1,
- .sync_edge = 1,
- .sync_ctrl = 1,
- .raster_order = 0,
-};
-
static const struct tilcdc_panel_info panel_info_default = {
.ac_bias = 255,
.ac_bias_intrpt = 0,
return NULL;
}
-int tilcdc_add_component_encoder(struct drm_device *ddev)
-{
- struct tilcdc_drm_private *priv = ddev->dev_private;
- struct drm_encoder *encoder = NULL, *iter;
-
- list_for_each_entry(iter, &ddev->mode_config.encoder_list, head)
- if (iter->possible_crtcs & (1 << priv->crtc->index)) {
- encoder = iter;
- break;
- }
-
- if (!encoder) {
- dev_err(ddev->dev, "%s: No suitable encoder found\n", __func__);
- return -ENODEV;
- }
-
- priv->external_connector =
- tilcdc_encoder_find_connector(ddev, encoder);
-
- if (!priv->external_connector)
- return -ENODEV;
-
- /* Only tda998x is supported at the moment. */
- tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_tda998x);
-
- return 0;
-}
-
static
int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge)
{
drm_encoder_cleanup(priv->external_encoder);
return ret;
}
-
-static int dev_match_of(struct device *dev, void *data)
-{
- return dev->of_node == data;
-}
-
-int tilcdc_get_external_components(struct device *dev,
- struct component_match **match)
-{
- struct device_node *node;
-
- node = of_graph_get_remote_node(dev->of_node, 0, 0);
-
- if (!of_device_is_compatible(node, "nxp,tda998x")) {
- of_node_put(node);
- return 0;
- }
-
- if (match)
- drm_of_component_match_add(dev, match, dev_match_of, node);
- of_node_put(node);
- return 1;
-}