Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

OMAPDSS: DT: Get source endpoint by matching reg-id

In omapdss_of_find_source_for_first_ep, we retrieve a source endpoint's DT node,
and then see what omapdss output has the matching device_node pointer in
omap_dss_find_output_by_node.

For all DPI and SDI outputs, the device_node pointer is set as the parent's DSS
device_node pointer. If the source is one of these outputs, the above method
won't work.

To get the correct output for ports within DSS(and in other cases in the future,
where multiple ports might be under one device), we require additional
information which is exclusive to the output port.

We create a new field in omap_dss_device called 'port_num', this provides port
number of the output port corresponding to this device. When searching for the
source endpoint in DT, we extract the 'reg' property from the port corresponding
to the endpoint source. From the list of registered outputs, we pick out that
output which has both dev->of_node and port_num matching with the device_node
pointer and 'reg' of the source endpoint node from DT.

For encoder blocks(the ones which have both an input and output port), we need
to set the port_num as the 'reg' property for the output port as defined in the
DT bindings. We set port_num to 1 in the tfp410 and tpd12s015 encoder drivers.

Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

authored by

Archit Taneja and committed by
Tomi Valkeinen
ef691ff4 387ce9f2

+66 -22
+1
drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
··· 249 249 dssdev->output_type = OMAP_DISPLAY_TYPE_DVI; 250 250 dssdev->owner = THIS_MODULE; 251 251 dssdev->phy.dpi.data_lines = ddata->data_lines; 252 + dssdev->port_num = 1; 252 253 253 254 r = omapdss_register_output(dssdev); 254 255 if (r) {
+1
drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
··· 409 409 dssdev->type = OMAP_DISPLAY_TYPE_HDMI; 410 410 dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; 411 411 dssdev->owner = THIS_MODULE; 412 + dssdev->port_num = 1; 412 413 413 414 in = ddata->in; 414 415
+40 -18
drivers/video/fbdev/omap2/dss/dss-of.c
··· 20 20 21 21 #include <video/omapdss.h> 22 22 23 + #include "dss.h" 24 + 23 25 struct device_node * 24 26 omapdss_of_get_next_port(const struct device_node *parent, 25 27 struct device_node *prev) ··· 86 84 } 87 85 EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint); 88 86 89 - static struct device_node * 90 - omapdss_of_get_remote_device_node(const struct device_node *node) 87 + struct device_node *dss_of_port_get_parent_device(struct device_node *port) 91 88 { 92 89 struct device_node *np; 93 90 int i; 94 91 95 - np = of_parse_phandle(node, "remote-endpoint", 0); 96 - 97 - if (!np) 92 + if (!port) 98 93 return NULL; 99 94 100 - np = of_get_next_parent(np); 95 + np = of_get_next_parent(port); 101 96 102 - for (i = 0; i < 3 && np; ++i) { 97 + for (i = 0; i < 2 && np; ++i) { 103 98 struct property *prop; 104 99 105 100 prop = of_find_property(np, "compatible", NULL); ··· 108 109 } 109 110 110 111 return NULL; 112 + } 113 + 114 + u32 dss_of_port_get_port_number(struct device_node *port) 115 + { 116 + int r; 117 + u32 reg; 118 + 119 + r = of_property_read_u32(port, "reg", &reg); 120 + if (r) 121 + reg = 0; 122 + 123 + return reg; 124 + } 125 + 126 + static struct device_node *omapdss_of_get_remote_port(const struct device_node *node) 127 + { 128 + struct device_node *np; 129 + 130 + np = of_parse_phandle(node, "remote-endpoint", 0); 131 + if (!np) 132 + return NULL; 133 + 134 + np = of_get_next_parent(np); 135 + 136 + return np; 111 137 } 112 138 113 139 struct device_node * ··· 157 133 omapdss_of_find_source_for_first_ep(struct device_node *node) 158 134 { 159 135 struct device_node *ep; 160 - struct device_node *src_node; 136 + struct device_node *src_port; 161 137 struct omap_dss_device *src; 162 138 163 139 ep = omapdss_of_get_first_endpoint(node); 164 140 if (!ep) 165 141 return ERR_PTR(-EINVAL); 166 142 167 - src_node = omapdss_of_get_remote_device_node(ep); 143 + src_port = omapdss_of_get_remote_port(ep); 144 + if (!src_port) { 145 + of_node_put(ep); 146 + return ERR_PTR(-EINVAL); 147 + } 168 148 169 149 of_node_put(ep); 170 150 171 - if (!src_node) 172 - return ERR_PTR(-EINVAL); 151 + src = omap_dss_find_output_by_port_node(src_port); 173 152 174 - src = omap_dss_find_output_by_node(src_node); 153 + of_node_put(src_port); 175 154 176 - of_node_put(src_node); 177 - 178 - if (!src) 179 - return ERR_PTR(-EPROBE_DEFER); 180 - 181 - return src; 155 + return src ? src : ERR_PTR(-EPROBE_DEFER); 182 156 } 183 157 EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep);
+4
drivers/video/fbdev/omap2/dss/dss.h
··· 215 215 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 216 216 void dss_dump_clocks(struct seq_file *s); 217 217 218 + /* dss-of */ 219 + struct device_node *dss_of_port_get_parent_device(struct device_node *port); 220 + u32 dss_of_port_get_port_number(struct device_node *port); 221 + 218 222 #if defined(CONFIG_OMAP2_DSS_DEBUGFS) 219 223 void dss_debug_dump_clocks(struct seq_file *s); 220 224 #endif
+16 -3
drivers/video/fbdev/omap2/dss/output.c
··· 19 19 #include <linux/module.h> 20 20 #include <linux/platform_device.h> 21 21 #include <linux/slab.h> 22 + #include <linux/of.h> 22 23 23 24 #include <video/omapdss.h> 24 25 ··· 132 131 } 133 132 EXPORT_SYMBOL(omap_dss_find_output); 134 133 135 - struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node) 134 + struct omap_dss_device *omap_dss_find_output_by_port_node(struct device_node *port) 136 135 { 136 + struct device_node *src_node; 137 137 struct omap_dss_device *out; 138 + u32 reg; 139 + 140 + src_node = dss_of_port_get_parent_device(port); 141 + if (!src_node) 142 + return NULL; 143 + 144 + reg = dss_of_port_get_port_number(port); 138 145 139 146 list_for_each_entry(out, &output_list, list) { 140 - if (out->dev->of_node == node) 147 + if (out->dev->of_node == src_node && out->port_num == reg) { 148 + of_node_put(src_node); 141 149 return omap_dss_get_device(out); 150 + } 142 151 } 152 + 153 + of_node_put(src_node); 143 154 144 155 return NULL; 145 156 } 146 - EXPORT_SYMBOL(omap_dss_find_output_by_node); 157 + EXPORT_SYMBOL(omap_dss_find_output_by_port_node); 147 158 148 159 struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev) 149 160 {
+4 -1
include/video/omapdss.h
··· 795 795 /* output instance */ 796 796 enum omap_dss_output_id id; 797 797 798 + /* the port number in the DT node */ 799 + int port_num; 800 + 798 801 /* dynamic fields */ 799 802 struct omap_overlay_manager *manager; 800 803 ··· 921 918 void omapdss_unregister_output(struct omap_dss_device *output); 922 919 struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id); 923 920 struct omap_dss_device *omap_dss_find_output(const char *name); 924 - struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node); 921 + struct omap_dss_device *omap_dss_find_output_by_port_node(struct device_node *port); 925 922 int omapdss_output_set_device(struct omap_dss_device *out, 926 923 struct omap_dss_device *dssdev); 927 924 int omapdss_output_unset_device(struct omap_dss_device *out);