1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | |
3 | /* |
4 | * Copyright 2019,2020,2022 NXP |
5 | */ |
6 | |
7 | #ifndef __IMX_LDB_HELPER__ |
8 | #define __IMX_LDB_HELPER__ |
9 | |
10 | #include <linux/device.h> |
11 | #include <linux/kernel.h> |
12 | #include <linux/of.h> |
13 | #include <linux/regmap.h> |
14 | |
15 | #include <drm/drm_atomic.h> |
16 | #include <drm/drm_bridge.h> |
17 | #include <drm/drm_device.h> |
18 | #include <drm/drm_encoder.h> |
19 | #include <drm/drm_modeset_helper_vtables.h> |
20 | |
21 | #define LDB_CH0_MODE_EN_TO_DI0 BIT(0) |
22 | #define LDB_CH0_MODE_EN_TO_DI1 (3 << 0) |
23 | #define LDB_CH0_MODE_EN_MASK (3 << 0) |
24 | #define LDB_CH1_MODE_EN_TO_DI0 BIT(2) |
25 | #define LDB_CH1_MODE_EN_TO_DI1 (3 << 2) |
26 | #define LDB_CH1_MODE_EN_MASK (3 << 2) |
27 | #define LDB_SPLIT_MODE_EN BIT(4) |
28 | #define LDB_DATA_WIDTH_CH0_24 BIT(5) |
29 | #define LDB_BIT_MAP_CH0_JEIDA BIT(6) |
30 | #define LDB_DATA_WIDTH_CH1_24 BIT(7) |
31 | #define LDB_BIT_MAP_CH1_JEIDA BIT(8) |
32 | #define LDB_DI0_VS_POL_ACT_LOW BIT(9) |
33 | #define LDB_DI1_VS_POL_ACT_LOW BIT(10) |
34 | |
35 | #define MAX_LDB_CHAN_NUM 2 |
36 | |
37 | enum ldb_channel_link_type { |
38 | LDB_CH_SINGLE_LINK, |
39 | LDB_CH_DUAL_LINK_EVEN_ODD_PIXELS, |
40 | LDB_CH_DUAL_LINK_ODD_EVEN_PIXELS, |
41 | }; |
42 | |
43 | struct ldb; |
44 | |
45 | struct ldb_channel { |
46 | struct ldb *ldb; |
47 | struct drm_bridge bridge; |
48 | struct drm_bridge *next_bridge; |
49 | struct device_node *np; |
50 | u32 chno; |
51 | bool is_available; |
52 | u32 in_bus_format; |
53 | u32 out_bus_format; |
54 | enum ldb_channel_link_type link_type; |
55 | }; |
56 | |
57 | struct ldb { |
58 | struct regmap *regmap; |
59 | struct device *dev; |
60 | struct ldb_channel *channel[MAX_LDB_CHAN_NUM]; |
61 | unsigned int ctrl_reg; |
62 | u32 ldb_ctrl; |
63 | unsigned int available_ch_cnt; |
64 | }; |
65 | |
66 | #define bridge_to_ldb_ch(b) container_of(b, struct ldb_channel, bridge) |
67 | |
68 | bool ldb_channel_is_single_link(struct ldb_channel *ldb_ch); |
69 | bool ldb_channel_is_split_link(struct ldb_channel *ldb_ch); |
70 | |
71 | int ldb_bridge_atomic_check_helper(struct drm_bridge *bridge, |
72 | struct drm_bridge_state *bridge_state, |
73 | struct drm_crtc_state *crtc_state, |
74 | struct drm_connector_state *conn_state); |
75 | |
76 | void ldb_bridge_mode_set_helper(struct drm_bridge *bridge, |
77 | const struct drm_display_mode *mode, |
78 | const struct drm_display_mode *adjusted_mode); |
79 | |
80 | void ldb_bridge_enable_helper(struct drm_bridge *bridge); |
81 | |
82 | void ldb_bridge_disable_helper(struct drm_bridge *bridge); |
83 | |
84 | int ldb_bridge_attach_helper(struct drm_bridge *bridge, |
85 | enum drm_bridge_attach_flags flags); |
86 | |
87 | int ldb_init_helper(struct ldb *ldb); |
88 | |
89 | int ldb_find_next_bridge_helper(struct ldb *ldb); |
90 | |
91 | void ldb_add_bridge_helper(struct ldb *ldb, |
92 | const struct drm_bridge_funcs *bridge_funcs); |
93 | |
94 | void ldb_remove_bridge_helper(struct ldb *ldb); |
95 | |
96 | #endif /* __IMX_LDB_HELPER__ */ |
97 | |