|
36 | 36 | #include "sun4i_rgb.h"
|
37 | 37 | #include "sun4i_tcon.h"
|
38 | 38 | #include "sun6i_mipi_dsi.h"
|
| 39 | +#include "sun8i_tcon_top.h" |
39 | 40 | #include "sunxi_engine.h"
|
40 | 41 |
|
41 | 42 | static struct drm_connector *sun4i_tcon_get_connector(const struct drm_encoder *encoder)
|
@@ -908,6 +909,36 @@ static struct sunxi_engine *sun4i_tcon_get_engine_by_id(struct sun4i_drv *drv,
|
908 | 909 | return ERR_PTR(-EINVAL);
|
909 | 910 | }
|
910 | 911 |
|
| 912 | +static bool sun4i_tcon_connected_to_tcon_top(struct device_node *node) |
| 913 | +{ |
| 914 | + struct device_node *remote; |
| 915 | + bool ret = false; |
| 916 | + |
| 917 | + remote = of_graph_get_remote_node(node, 0, -1); |
| 918 | + if (remote) { |
| 919 | + ret = !!of_match_node(sun8i_tcon_top_of_table, remote); |
| 920 | + of_node_put(remote); |
| 921 | + } |
| 922 | + |
| 923 | + return ret; |
| 924 | +} |
| 925 | + |
| 926 | +static int sun4i_tcon_get_index(struct sun4i_drv *drv) |
| 927 | +{ |
| 928 | + struct list_head *pos; |
| 929 | + int size = 0; |
| 930 | + |
| 931 | + /* |
| 932 | + * Because TCON is added to the list at the end of the probe |
| 933 | + * (after this function is called), index of the current TCON |
| 934 | + * will be same as current TCON list size. |
| 935 | + */ |
| 936 | + list_for_each(pos, &drv->tcon_list) |
| 937 | + ++size; |
| 938 | + |
| 939 | + return size; |
| 940 | +} |
| 941 | + |
911 | 942 | /*
|
912 | 943 | * On SoCs with the old display pipeline design (Display Engine 1.0),
|
913 | 944 | * we assumed the TCON was always tied to just one backend. However
|
@@ -956,8 +987,24 @@ static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv,
|
956 | 987 | * connections between the backend and TCON?
|
957 | 988 | */
|
958 | 989 | if (of_get_child_count(port) > 1) {
|
959 |
| - /* Get our ID directly from an upstream endpoint */ |
960 |
| - int id = sun4i_tcon_of_get_id_from_port(port); |
| 990 | + int id; |
| 991 | + |
| 992 | + /* |
| 993 | + * When pipeline has the same number of TCONs and engines which |
| 994 | + * are represented by frontends/backends (DE1) or mixers (DE2), |
| 995 | + * we match them by their respective IDs. However, if pipeline |
| 996 | + * contains TCON TOP, chances are that there are either more |
| 997 | + * TCONs than engines (R40) or TCONs with non-consecutive ids. |
| 998 | + * (H6). In that case it's easier just use TCON index in list |
| 999 | + * as an id. That means that on R40, any 2 TCONs can be enabled |
| 1000 | + * in DT out of 4 (there are 2 mixers). Due to the design of |
| 1001 | + * TCON TOP, remaining 2 TCONs can't be connected to anything |
| 1002 | + * anyway. |
| 1003 | + */ |
| 1004 | + if (sun4i_tcon_connected_to_tcon_top(node)) |
| 1005 | + id = sun4i_tcon_get_index(drv); |
| 1006 | + else |
| 1007 | + id = sun4i_tcon_of_get_id_from_port(port); |
961 | 1008 |
|
962 | 1009 | /* Get our engine by matching our ID */
|
963 | 1010 | engine = sun4i_tcon_get_engine_by_id(drv, id);
|
|
0 commit comments