fsl_ldb
static inline struct fsl_ldb *to_fsl_ldb(struct drm_bridge *bridge)
return container_of(bridge, struct fsl_ldb, bridge);
static unsigned long fsl_ldb_link_frequency(struct fsl_ldb *fsl_ldb, int clock)
if (fsl_ldb_is_dual(fsl_ldb))
struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
return drm_bridge_attach(encoder, fsl_ldb->panel_bridge,
struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
dev_warn(fsl_ldb->dev,
requested_link_freq = fsl_ldb_link_frequency(fsl_ldb, mode->clock);
clk_set_rate(fsl_ldb->clk, requested_link_freq);
configured_link_freq = clk_get_rate(fsl_ldb->clk);
dev_warn(fsl_ldb->dev,
fsl_ldb->clk, configured_link_freq, requested_link_freq);
clk_prepare_enable(fsl_ldb->clk);
reg = (fsl_ldb->ch0_enabled ? LDB_CTRL_CH0_ENABLE : 0) |
(fsl_ldb->ch1_enabled ? LDB_CTRL_CH1_ENABLE : 0) |
(fsl_ldb_is_dual(fsl_ldb) ? LDB_CTRL_SPLIT_MODE : 0);
reg |= (fsl_ldb->ch0_enabled ? LDB_CTRL_CH0_DATA_WIDTH : 0) |
(fsl_ldb->ch1_enabled ? LDB_CTRL_CH1_DATA_WIDTH : 0);
reg |= (fsl_ldb->ch0_enabled ? LDB_CTRL_CH0_BIT_MAPPING : 0) |
(fsl_ldb->ch1_enabled ? LDB_CTRL_CH1_BIT_MAPPING : 0);
reg |= (fsl_ldb->ch0_enabled ? LDB_CTRL_DI0_VSYNC_POLARITY : 0) |
(fsl_ldb->ch1_enabled ? LDB_CTRL_DI1_VSYNC_POLARITY : 0);
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, reg);
if (fsl_ldb->devdata->single_ctrl_reg)
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, reg);
reg |= (fsl_ldb->ch0_enabled ? LVDS_CTRL_CH0_EN : 0) |
(fsl_ldb->ch1_enabled ? LVDS_CTRL_CH1_EN : 0);
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, reg);
struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
if (fsl_ldb->devdata->lvds_en_bit)
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl,
if (!fsl_ldb->devdata->single_ctrl_reg)
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->lvds_ctrl, 0);
regmap_write(fsl_ldb->regmap, fsl_ldb->devdata->ldb_ctrl, 0);
clk_disable_unprepare(fsl_ldb->clk);
struct fsl_ldb *fsl_ldb = to_fsl_ldb(bridge);
if (mode->clock > (fsl_ldb_is_dual(fsl_ldb) ? 160000 : 80000))
struct fsl_ldb *fsl_ldb;
fsl_ldb = devm_drm_bridge_alloc(dev, struct fsl_ldb, bridge, &funcs);
if (IS_ERR(fsl_ldb))
return PTR_ERR(fsl_ldb);
fsl_ldb->devdata = of_device_get_match_data(dev);
if (!fsl_ldb->devdata)
fsl_ldb->dev = &pdev->dev;
fsl_ldb->bridge.of_node = dev->of_node;
fsl_ldb->clk = devm_clk_get(dev, "ldb");
if (IS_ERR(fsl_ldb->clk))
return PTR_ERR(fsl_ldb->clk);
fsl_ldb->regmap = syscon_node_to_regmap(dev->of_node->parent);
if (IS_ERR(fsl_ldb->regmap))
return PTR_ERR(fsl_ldb->regmap);
fsl_ldb->ch0_enabled = (remote1 != NULL);
fsl_ldb->ch1_enabled = (remote2 != NULL);
if (!fsl_ldb->ch0_enabled && !fsl_ldb->ch1_enabled) {
fsl_ldb_is_dual(fsl_ldb) ? "dual-link mode" :
fsl_ldb->ch0_enabled ? "channel 0" : "channel 1");
fsl_ldb->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
if (IS_ERR(fsl_ldb->panel_bridge))
return PTR_ERR(fsl_ldb->panel_bridge);
if (fsl_ldb_is_dual(fsl_ldb)) {
platform_set_drvdata(pdev, fsl_ldb);
drm_bridge_add(&fsl_ldb->bridge);
struct fsl_ldb *fsl_ldb = platform_get_drvdata(pdev);
drm_bridge_remove(&fsl_ldb->bridge);
static bool fsl_ldb_is_dual(const struct fsl_ldb *fsl_ldb)
return (fsl_ldb->ch0_enabled && fsl_ldb->ch1_enabled);