drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c- Extension
.c- Size
- 20490 bytes
- Lines
- 733
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/media-bus-format.hlinux/mfd/syscon.hlinux/module.hlinux/of.hlinux/of_device.hlinux/of_graph.hlinux/phy/phy.hlinux/platform_device.hlinux/pm_runtime.hlinux/regmap.hdrm/drm_atomic_state_helper.hdrm/drm_bridge.hdrm/drm_connector.hdrm/drm_fourcc.hdrm/drm_of.hdrm/drm_print.himx-ldb-helper.h
Detected Declarations
struct imx8qxp_ldb_channelstruct imx8qxp_ldbfunction base_to_imx8qxp_ldb_channelfunction imx8qxp_ldb_bridge_destroyfunction imx8qxp_ldb_set_phy_cfgfunction imx8qxp_ldb_bridge_atomic_checkfunction imx8qxp_ldb_bridge_mode_setfunction imx8qxp_ldb_bridge_atomic_pre_enablefunction imx8qxp_ldb_bridge_atomic_enablefunction imx8qxp_ldb_bridge_atomic_disablefunction imx8qxp_ldb_bus_output_fmt_supportedfunction imx8qxp_ldb_bridge_atomic_get_input_bus_fmtsfunction imx8qxp_ldb_bridge_atomic_get_output_bus_fmtsfunction imx8qxp_ldb_bridge_mode_validfunction imx8qxp_ldb_set_di_idfunction imx8qxp_ldb_check_chno_and_dual_linkfunction imx8qxp_ldb_parse_dt_companionfunction for_each_available_child_of_nodefunction imx8qxp_ldb_probefunction imx8qxp_ldb_removefunction imx8qxp_ldb_runtime_resume
Annotated Snippet
struct imx8qxp_ldb_channel {
struct ldb_channel base;
struct phy *phy;
unsigned int di_id;
};
struct imx8qxp_ldb {
struct ldb base;
struct device *dev;
struct imx8qxp_ldb_channel *channel[MAX_LDB_CHAN_NUM];
struct clk *clk_pixel;
struct clk *clk_bypass;
struct drm_bridge *companion;
int active_chno;
};
static inline struct imx8qxp_ldb_channel *
base_to_imx8qxp_ldb_channel(struct ldb_channel *base)
{
return container_of(base, struct imx8qxp_ldb_channel, base);
}
static inline struct imx8qxp_ldb *base_to_imx8qxp_ldb(struct ldb *base)
{
return container_of(base, struct imx8qxp_ldb, base);
}
static void imx8qxp_ldb_bridge_destroy(struct drm_bridge *bridge)
{
struct ldb_channel *ldb_ch = bridge->driver_private;
struct imx8qxp_ldb *imx8qxp_ldb;
if (!ldb_ch)
return;
imx8qxp_ldb = base_to_imx8qxp_ldb(ldb_ch->ldb);
drm_bridge_put(imx8qxp_ldb->companion);
}
static void imx8qxp_ldb_set_phy_cfg(struct imx8qxp_ldb *imx8qxp_ldb,
unsigned long di_clk, bool is_split,
struct phy_configure_opts_lvds *phy_cfg)
{
phy_cfg->bits_per_lane_and_dclk_cycle = 7;
phy_cfg->lanes = 4;
if (is_split) {
phy_cfg->differential_clk_rate = di_clk / 2;
phy_cfg->is_slave = !imx8qxp_ldb->companion;
} else {
phy_cfg->differential_clk_rate = di_clk;
phy_cfg->is_slave = false;
}
}
static int
imx8qxp_ldb_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
struct ldb_channel *ldb_ch = bridge->driver_private;
struct ldb *ldb = ldb_ch->ldb;
struct imx8qxp_ldb_channel *imx8qxp_ldb_ch =
base_to_imx8qxp_ldb_channel(ldb_ch);
struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb);
struct drm_bridge *companion = imx8qxp_ldb->companion;
struct drm_display_mode *adj = &crtc_state->adjusted_mode;
unsigned long di_clk = adj->clock * 1000;
bool is_split = ldb_channel_is_split_link(ldb_ch);
union phy_configure_opts opts = { };
struct phy_configure_opts_lvds *phy_cfg = &opts.lvds;
int ret;
ret = ldb_bridge_atomic_check_helper(bridge, bridge_state,
crtc_state, conn_state);
if (ret)
return ret;
imx8qxp_ldb_set_phy_cfg(imx8qxp_ldb, di_clk, is_split, phy_cfg);
ret = phy_validate(imx8qxp_ldb_ch->phy, PHY_MODE_LVDS, 0, &opts);
if (ret < 0) {
DRM_DEV_DEBUG_DRIVER(imx8qxp_ldb->dev,
"failed to validate PHY: %d\n", ret);
return ret;
}
if (is_split && companion) {
ret = companion->funcs->atomic_check(companion,
bridge_state, crtc_state, conn_state);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/media-bus-format.h`, `linux/mfd/syscon.h`, `linux/module.h`, `linux/of.h`, `linux/of_device.h`, `linux/of_graph.h`, `linux/phy/phy.h`.
- Detected declarations: `struct imx8qxp_ldb_channel`, `struct imx8qxp_ldb`, `function base_to_imx8qxp_ldb_channel`, `function imx8qxp_ldb_bridge_destroy`, `function imx8qxp_ldb_set_phy_cfg`, `function imx8qxp_ldb_bridge_atomic_check`, `function imx8qxp_ldb_bridge_mode_set`, `function imx8qxp_ldb_bridge_atomic_pre_enable`, `function imx8qxp_ldb_bridge_atomic_enable`, `function imx8qxp_ldb_bridge_atomic_disable`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.