@@ -107,13 +107,13 @@ def __init__(self, prefix: str, size: str) -> None:
107107 self .prefix = prefix
108108 self .size = size
109109
110- def __init__ (self , fdt : Fdt2 , node : int , t : Type ) -> None :
110+ def __init__ (self , fdt : Fdt2 , panel_node : int , mode_node : int , t : Type ) -> None :
111111 self .type = type
112- self .px = fdt .getprop (node , f'qcom,mdss-dsi-panel-{ t .size } ' ).as_int32 ()
113- self .fp = fdt .getprop (node , f'qcom,mdss-dsi-{ t .prefix } -front-porch' ).as_int32 ()
114- self .bp = fdt .getprop (node , f'qcom,mdss-dsi-{ t .prefix } -back-porch' ).as_int32 ()
115- self .pw = fdt .getprop (node , f'qcom,mdss-dsi-{ t .prefix } -pulse-width' ).as_int32 ()
116- self .size = fdt .getprop_int32 (node , f'qcom,mdss-pan-physical-{ t .size } -dimension' )
112+ self .px = fdt .getprop (mode_node , f'qcom,mdss-dsi-panel-{ t .size } ' ).as_int32 ()
113+ self .fp = fdt .getprop (mode_node , f'qcom,mdss-dsi-{ t .prefix } -front-porch' ).as_int32 ()
114+ self .bp = fdt .getprop (mode_node , f'qcom,mdss-dsi-{ t .prefix } -back-porch' ).as_int32 ()
115+ self .pw = fdt .getprop (mode_node , f'qcom,mdss-dsi-{ t .prefix } -pulse-width' ).as_int32 ()
116+ self .size = fdt .getprop_int32 (panel_node , f'qcom,mdss-pan-physical-{ t .size } -dimension' )
117117
118118
119119@dataclass
@@ -184,6 +184,22 @@ def _remove_before(text: str, sub: str) -> str:
184184 return text [i + 1 :] if i >= 0 else text
185185
186186
187+ def _find_mode_node (fdt : Fdt2 , node : int ) -> int :
188+ timings_node = fdt .subnode_or_none (node , "qcom,mdss-dsi-display-timings" )
189+ if timings_node is None :
190+ return node
191+
192+ mode_node = None
193+ for timing in fdt .subnodes (timings_node ):
194+ if mode_node :
195+ print ("WARNING: Multiple display timings are not supported yet, using first!" )
196+ break
197+ mode_node = timing
198+
199+ assert mode_node , "No display timings found"
200+ return mode_node
201+
202+
187203class Panel :
188204 def __init__ (self , name : str , fdt : Fdt2 , node : int ) -> None :
189205 self .name = name
@@ -192,9 +208,14 @@ def __init__(self, name: str, fdt: Fdt2, node: int) -> None:
192208 self .short_id = _replace_all (self .id , '_panel' , '_video' , '_vid' , '_cmd' ,
193209 '_hd' , '_qhd' , '_720p' , '_1080p' ,
194210 '_wvga' , '_fwvga' , '_qvga' , '_xga' , '_wxga' )
195- self .h = Dimension (fdt , node , Dimension .Type .HORIZONTAL )
196- self .v = Dimension (fdt , node , Dimension .Type .VERTICAL )
197- self .framerate = fdt .getprop (node , 'qcom,mdss-dsi-panel-framerate' ).as_int32 ()
211+
212+ # Newer SoCs can use panels in different modes (resolution, refresh rate etc).
213+ # We don't support this properly yet but many panels just have a single mode
214+ # ("timing") defined, so let's try to support this here.
215+ mode_node = _find_mode_node (fdt , node )
216+ self .h = Dimension (fdt , node , mode_node , Dimension .Type .HORIZONTAL )
217+ self .v = Dimension (fdt , node , mode_node , Dimension .Type .VERTICAL )
218+ self .framerate = fdt .getprop (mode_node , 'qcom,mdss-dsi-panel-framerate' ).as_int32 ()
198219 self .bpp = fdt .getprop (node , 'qcom,mdss-dsi-bpp' ).as_int32 ()
199220 self .mode = Mode (fdt .getprop (node , 'qcom,mdss-dsi-panel-type' ).as_str ())
200221 self .traffic_mode = TrafficMode .parse (fdt .getprop (node , 'qcom,mdss-dsi-traffic-mode' ))
@@ -227,8 +248,8 @@ def __init__(self, name: str, fdt: Fdt2, node: int) -> None:
227248 self .reset_seq = None
228249
229250 self .cmds = {
230- 'on' : CommandSequence (fdt , node , 'on' ),
231- 'off' : CommandSequence (fdt , node , 'off' )
251+ 'on' : CommandSequence (fdt , mode_node , 'on' ),
252+ 'off' : CommandSequence (fdt , mode_node , 'off' )
232253 }
233254
234255 # If all commands are sent in LPM, add flag globally
@@ -259,3 +280,13 @@ def find(fdt: Fdt2) -> Iterator[Panel]:
259280 panel = Panel .parse (fdt , sub )
260281 if panel :
261282 yield panel
283+
284+ # Newer device trees do not necessarily have panels below MDP,
285+ # search for qcom,dsi-display node instead
286+ for display in fdt .find_by_compatible ('qcom,dsi-display' ):
287+ # Actual display node is pointed to by qcom,dsi-panel
288+ phandle = fdt .getprop (display , 'qcom,dsi-panel' ).as_uint32 ()
289+ offset = fdt .node_offset_by_phandle (phandle )
290+ panel = Panel .parse (fdt , offset )
291+ if panel :
292+ yield panel
0 commit comments