drivers/gpu/drm/bridge/imx/imx8qm-ldb.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/bridge/imx/imx8qm-ldb.c- Extension
.c- Size
- 16330 bytes
- Lines
- 590
- 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_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 imx8qm_ldb_channelstruct imx8qm_ldbfunction base_to_imx8qm_ldb_channelfunction imx8qm_ldb_set_phy_cfgfunction imx8qm_ldb_bridge_atomic_checkfunction imx8qm_ldb_bridge_mode_setfunction imx8qm_ldb_bridge_atomic_enablefunction imx8qm_ldb_bridge_atomic_disablefunction imx8qm_ldb_bus_output_fmt_supportedfunction imx8qm_ldb_bridge_atomic_get_input_bus_fmtsfunction imx8qm_ldb_bridge_atomic_get_output_bus_fmtsfunction imx8qm_ldb_bridge_mode_validfunction imx8qm_ldb_get_phyfunction imx8qm_ldb_probefunction imx8qm_ldb_removefunction imx8qm_ldb_runtime_suspendfunction imx8qm_ldb_runtime_resume
Annotated Snippet
struct imx8qm_ldb_channel {
struct ldb_channel base;
struct phy *phy;
};
struct imx8qm_ldb {
struct ldb base;
struct device *dev;
struct imx8qm_ldb_channel *channel[MAX_LDB_CHAN_NUM];
struct clk *clk_pixel;
struct clk *clk_bypass;
int active_chno;
};
static inline struct imx8qm_ldb_channel *
base_to_imx8qm_ldb_channel(struct ldb_channel *base)
{
return container_of(base, struct imx8qm_ldb_channel, base);
}
static inline struct imx8qm_ldb *base_to_imx8qm_ldb(struct ldb *base)
{
return container_of(base, struct imx8qm_ldb, base);
}
static void imx8qm_ldb_set_phy_cfg(struct imx8qm_ldb *imx8qm_ldb,
unsigned long di_clk,
bool is_split, bool is_slave,
struct phy_configure_opts_lvds *phy_cfg)
{
phy_cfg->bits_per_lane_and_dclk_cycle = 7;
phy_cfg->lanes = 4;
phy_cfg->differential_clk_rate = is_split ? di_clk / 2 : di_clk;
phy_cfg->is_slave = is_slave;
}
static int imx8qm_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 imx8qm_ldb_channel *imx8qm_ldb_ch =
base_to_imx8qm_ldb_channel(ldb_ch);
struct imx8qm_ldb *imx8qm_ldb = base_to_imx8qm_ldb(ldb);
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;
imx8qm_ldb_set_phy_cfg(imx8qm_ldb, di_clk, is_split, false, phy_cfg);
ret = phy_validate(imx8qm_ldb_ch->phy, PHY_MODE_LVDS, 0, &opts);
if (ret < 0) {
DRM_DEV_DEBUG_DRIVER(imx8qm_ldb->dev,
"failed to validate PHY: %d\n", ret);
return ret;
}
if (is_split) {
imx8qm_ldb_ch =
imx8qm_ldb->channel[imx8qm_ldb->active_chno ^ 1];
imx8qm_ldb_set_phy_cfg(imx8qm_ldb, di_clk, is_split, true,
phy_cfg);
ret = phy_validate(imx8qm_ldb_ch->phy, PHY_MODE_LVDS, 0, &opts);
if (ret < 0) {
DRM_DEV_DEBUG_DRIVER(imx8qm_ldb->dev,
"failed to validate slave PHY: %d\n",
ret);
return ret;
}
}
return ret;
}
static void
imx8qm_ldb_bridge_mode_set(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
const struct drm_display_mode *adjusted_mode)
{
struct ldb_channel *ldb_ch = bridge->driver_private;
struct ldb *ldb = ldb_ch->ldb;
Annotation
- Immediate include surface: `linux/clk.h`, `linux/media-bus-format.h`, `linux/mfd/syscon.h`, `linux/module.h`, `linux/of.h`, `linux/of_graph.h`, `linux/phy/phy.h`, `linux/platform_device.h`.
- Detected declarations: `struct imx8qm_ldb_channel`, `struct imx8qm_ldb`, `function base_to_imx8qm_ldb_channel`, `function imx8qm_ldb_set_phy_cfg`, `function imx8qm_ldb_bridge_atomic_check`, `function imx8qm_ldb_bridge_mode_set`, `function imx8qm_ldb_bridge_atomic_enable`, `function imx8qm_ldb_bridge_atomic_disable`, `function imx8qm_ldb_bus_output_fmt_supported`, `function imx8qm_ldb_bridge_atomic_get_input_bus_fmts`.
- 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.