mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-27 19:09:50 -04:00
If the DSI panel supports versatile lanes configuration, its driver might require determining the number of DSI data lanes, which is usually specified on the DSI host side of the OF graph. Add new helper as a pair to drm_of_get_data_lanes_count_ep() that lets callers determine number of data-lanes on the remote side of the OF graph. Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patch.msgid.link/20260413-waveshare-dsi-touch-v3-6-3aeb53022c32@oss.qualcomm.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
220 lines
5.9 KiB
C
220 lines
5.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef __DRM_OF_H__
|
|
#define __DRM_OF_H__
|
|
|
|
#include <linux/err.h>
|
|
#include <linux/of_graph.h>
|
|
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE)
|
|
#include <linux/of.h>
|
|
#include <drm/drm_bridge.h>
|
|
#endif
|
|
|
|
struct component_master_ops;
|
|
struct component_match;
|
|
struct device;
|
|
struct drm_device;
|
|
struct drm_encoder;
|
|
struct drm_panel;
|
|
struct drm_bridge;
|
|
struct device_node;
|
|
struct mipi_dsi_device_info;
|
|
struct mipi_dsi_host;
|
|
|
|
/**
|
|
* enum drm_lvds_dual_link_pixels - Pixel order of an LVDS dual-link connection
|
|
* @DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS: Even pixels are expected to be generated
|
|
* from the first port, odd pixels from the second port
|
|
* @DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS: Odd pixels are expected to be generated
|
|
* from the first port, even pixels from the second port
|
|
*/
|
|
enum drm_lvds_dual_link_pixels {
|
|
DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS = 0,
|
|
DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS = 1,
|
|
};
|
|
|
|
#ifdef CONFIG_OF
|
|
uint32_t drm_of_crtc_port_mask(struct drm_device *dev,
|
|
struct device_node *port);
|
|
uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
|
|
struct device_node *port);
|
|
void drm_of_component_match_add(struct device *master,
|
|
struct component_match **matchptr,
|
|
int (*compare)(struct device *, void *),
|
|
struct device_node *node);
|
|
int drm_of_component_probe(struct device *dev,
|
|
int (*compare_of)(struct device *, void *),
|
|
const struct component_master_ops *m_ops);
|
|
int drm_of_encoder_active_endpoint(struct device_node *node,
|
|
struct drm_encoder *encoder,
|
|
struct of_endpoint *endpoint);
|
|
int drm_of_find_panel_or_bridge(const struct device_node *np,
|
|
int port, int endpoint,
|
|
struct drm_panel **panel,
|
|
struct drm_bridge **bridge);
|
|
int drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1,
|
|
const struct device_node *port2);
|
|
int drm_of_lvds_get_dual_link_pixel_order_sink(struct device_node *port1,
|
|
struct device_node *port2);
|
|
int drm_of_lvds_get_data_mapping(const struct device_node *port);
|
|
int drm_of_get_data_lanes_count(const struct device_node *endpoint,
|
|
const unsigned int min, const unsigned int max);
|
|
int drm_of_get_data_lanes_count_ep(const struct device_node *port,
|
|
int port_reg, int reg,
|
|
const unsigned int min,
|
|
const unsigned int max);
|
|
int drm_of_get_data_lanes_count_remote(const struct device_node *port,
|
|
int port_reg, int reg,
|
|
const unsigned int min,
|
|
const unsigned int max);
|
|
#else
|
|
static inline uint32_t drm_of_crtc_port_mask(struct drm_device *dev,
|
|
struct device_node *port)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
|
|
struct device_node *port)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline void
|
|
drm_of_component_match_add(struct device *master,
|
|
struct component_match **matchptr,
|
|
int (*compare)(struct device *, void *),
|
|
struct device_node *node)
|
|
{
|
|
}
|
|
|
|
static inline int
|
|
drm_of_component_probe(struct device *dev,
|
|
int (*compare_of)(struct device *, void *),
|
|
const struct component_master_ops *m_ops)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int drm_of_encoder_active_endpoint(struct device_node *node,
|
|
struct drm_encoder *encoder,
|
|
struct of_endpoint *endpoint)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline int drm_of_find_panel_or_bridge(const struct device_node *np,
|
|
int port, int endpoint,
|
|
struct drm_panel **panel,
|
|
struct drm_bridge **bridge)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int
|
|
drm_of_lvds_get_dual_link_pixel_order(const struct device_node *port1,
|
|
const struct device_node *port2)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int
|
|
drm_of_lvds_get_dual_link_pixel_order_sink(struct device_node *port1,
|
|
struct device_node *port2)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int
|
|
drm_of_lvds_get_data_mapping(const struct device_node *port)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int
|
|
drm_of_get_data_lanes_count(const struct device_node *endpoint,
|
|
const unsigned int min, const unsigned int max)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int
|
|
drm_of_get_data_lanes_count_ep(const struct device_node *port,
|
|
int port_reg, int reg,
|
|
const unsigned int min,
|
|
const unsigned int max)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int
|
|
drm_of_get_data_lanes_count_remote(const struct device_node *port,
|
|
int port_reg, int reg,
|
|
const unsigned int min,
|
|
const unsigned int max)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
#endif
|
|
|
|
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_MIPI_DSI)
|
|
struct mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev);
|
|
#else
|
|
static inline struct
|
|
mipi_dsi_host *drm_of_get_dsi_bus(struct device *dev)
|
|
{
|
|
return ERR_PTR(-EINVAL);
|
|
}
|
|
#endif /* CONFIG_OF && CONFIG_DRM_MIPI_DSI */
|
|
|
|
/*
|
|
* drm_of_panel_bridge_remove - remove panel bridge
|
|
* @np: device tree node containing panel bridge output ports
|
|
*
|
|
* Remove the panel bridge of a given DT node's port and endpoint number
|
|
*
|
|
* Returns zero if successful, or one of the standard error codes if it fails.
|
|
*/
|
|
static inline int drm_of_panel_bridge_remove(const struct device_node *np,
|
|
int port, int endpoint)
|
|
{
|
|
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE)
|
|
struct drm_bridge *bridge;
|
|
struct device_node *remote;
|
|
|
|
remote = of_graph_get_remote_node(np, port, endpoint);
|
|
if (!remote)
|
|
return -ENODEV;
|
|
|
|
bridge = of_drm_find_and_get_bridge(remote);
|
|
drm_panel_bridge_remove(bridge);
|
|
|
|
drm_bridge_put(bridge);
|
|
of_node_put(remote);
|
|
|
|
return 0;
|
|
#else
|
|
return -EINVAL;
|
|
#endif
|
|
}
|
|
|
|
static inline int drm_of_encoder_active_endpoint_id(struct device_node *node,
|
|
struct drm_encoder *encoder)
|
|
{
|
|
struct of_endpoint endpoint;
|
|
int ret = drm_of_encoder_active_endpoint(node, encoder,
|
|
&endpoint);
|
|
|
|
return ret ?: endpoint.id;
|
|
}
|
|
|
|
static inline int drm_of_encoder_active_port_id(struct device_node *node,
|
|
struct drm_encoder *encoder)
|
|
{
|
|
struct of_endpoint endpoint;
|
|
int ret = drm_of_encoder_active_endpoint(node, encoder,
|
|
&endpoint);
|
|
|
|
return ret ?: endpoint.port;
|
|
}
|
|
|
|
#endif /* __DRM_OF_H__ */
|