Example #1
0
	def __init__(self, fdt: Fdt2, node: int, t: Type) -> None:
		self.type = type
		self.px = fdt.getprop(node, f'qcom,mdss-dsi-panel-{t.size}').as_int32()
		self.fp = fdt.getprop(node, f'qcom,mdss-dsi-{t.prefix}-front-porch').as_int32()
		self.bp = fdt.getprop(node, f'qcom,mdss-dsi-{t.prefix}-back-porch').as_int32()
		self.pw = fdt.getprop(node, f'qcom,mdss-dsi-{t.prefix}-pulse-width').as_int32()
		self.size = fdt.getprop_int32(node, f'qcom,mdss-pan-physical-{t.size}-dimension')
Example #2
0
	def __init__(self, fdt: Fdt2, node: int, cmd: str) -> None:
		self.state = CommandSequence.State(fdt.getprop(node, f'qcom,mdss-dsi-{cmd}-command-state').as_str())
		self.seq = []

		prop = fdt.getprop_or_none(node, f'qcom,mdss-dsi-{cmd}-command')
		if prop is None:
			print(f'Warning: qcom,mdss-dsi-{cmd}-command does not exist')
			return  # No commands
		itr = iter(prop)

		if cmd == 'on':
			# WHY SONY, WHY?????? Just put it in on-command...
			init = fdt.getprop_or_none(node, 'somc,mdss-dsi-init-command')
			if init:
				itr = itertools.chain(init, itr)

		for dtype in itr:
			last, vc, ack, wait = next(itr), next(itr), next(itr), next(itr)
			dlen = next(itr) << 8 | next(itr)
			payload = bytes(next(itr) for _ in range(0, dlen))

			t = mipi.Transaction(dtype)

			# Very often there are too many arguments encoded in the command stream.
			# These are redundant, because they would be never sent anyway.
			max_dlen = t.max_args + 1
			if 0 < max_dlen < dlen:
				payload = payload[:max_dlen]

			self.seq.append(Command(t, last, vc, ack, wait, payload))
 def __init__(self, fdt: Fdt2, panel_node: int, mode_node: int,
              t: Type) -> None:
     self.type = type
     if t.size == "width":
         self.px = fdt.getprop(mode_node,
                               f'qcom,mdss-pan-res').as_uint32_array()[1]
         self.fp = fdt.getprop(
             mode_node, f'qcom,mdss-pan-porch-values').as_uint32_array()[5]
         self.bp = fdt.getprop(
             mode_node, f'qcom,mdss-pan-porch-values').as_uint32_array()[3]
         self.pw = fdt.getprop(
             mode_node, f'qcom,mdss-pan-porch-values').as_uint32_array()[4]
         self.size = fdt.getprop(panel_node,
                                 f'qcom,mdss-pan-size').as_uint32_array()[0]
     elif t.size == "height":
         self.px = fdt.getprop(mode_node,
                               f'qcom,mdss-pan-res').as_uint32_array()[0]
         self.fp = fdt.getprop(
             mode_node, f'qcom,mdss-pan-porch-values').as_uint32_array()[2]
         self.bp = fdt.getprop(
             mode_node, f'qcom,mdss-pan-porch-values').as_uint32_array()[0]
         self.pw = fdt.getprop(
             mode_node, f'qcom,mdss-pan-porch-values').as_uint32_array()[1]
         self.size = fdt.getprop(panel_node,
                                 f'qcom,mdss-pan-size').as_uint32_array()[1]
     else:
         raise ValueError(f'Unknown dimension {t.size}')
    def find(fdt: Fdt2) -> Iterator[Panel]:
        for mdp in fdt.find_by_compatible('qcom,mdss_mdp'):
            for sub in fdt.subnodes(mdp):
                panel = Panel.parse(fdt, sub)
                if panel:
                    yield panel

        # Newer device trees do not necessarily have panels below MDP,
        # search for qcom,dsi-display node instead
        panel_phandles = set()

        for display in fdt.find_by_compatible('qcom,dsi-display'):
            # On even newer SoCs there is another node with qcom,dsi-display-list
            displays = fdt.getprop_or_none(display, 'qcom,dsi-display-list')
            if displays is None:
                panel_phandles.add(
                    fdt.getprop(display, 'qcom,dsi-panel').as_uint32())
            else:
                for display_phandle in displays.as_uint32_array():
                    display = fdt.node_offset_by_phandle(display_phandle)
                    panel_phandles.add(
                        fdt.getprop(display, 'qcom,dsi-panel').as_uint32())

        for phandle in panel_phandles:
            offset = fdt.node_offset_by_phandle(phandle)
            panel = Panel.parse(fdt, offset)
            if panel:
                yield panel
def _find_mode_node(fdt: Fdt2, node: int) -> int:
	timings_node = fdt.subnode_or_none(node, "qcom,mdss-dsi-display-timings")
	if timings_node is None:
		return node

	mode_node = None
	for timing in fdt.subnodes(timings_node):
		if mode_node:
			print("WARNING: Multiple display timings are not supported yet, using first!")
			break
		mode_node = timing

	assert mode_node, "No display timings found"
	return mode_node
                    default=0,
                    help="""
	Ignore wait in command sequences that is smaller that the specified value.
	Some device trees add a useless 1ms wait after each command, making the driver
	unnecessarily verbose.
""")
parser.add_argument('--dumb-dcs',
                    dest='dumb_dcs',
                    action='store_true',
                    help="""
	Do not attempt to interpret DCS commands. Some panels use arbitrary DCS commands
	to write to registers, which conflict with commands specified in the MIPI DCS
	specification. This option stops interpretation of DCS commands, except for
	enter/exit_sleep_mode and set_display_on/off (which should be supported by
	any panel ideally).
""")
args = parser.parse_args(namespace=generator.Options())

for f in args.dtb:
    with f:
        print(f"Parsing: {f.name}")
        fdt = Fdt2(f.read())

        found = False
        for panel in Panel.find(fdt):
            found = True
            generate(panel, args)

        if not found:
            print(f"{f.name} does not contain any panel specifications")
Example #7
0
	def find(fdt: Fdt2) -> Iterator[Panel]:
		for mdp in fdt.find_by_compatible('qcom,mdss_mdp'):
			for sub in fdt.subnodes(mdp):
				panel = Panel.parse(fdt, sub)
				if panel:
					yield panel
Example #8
0
	def parse(fdt: Fdt2, node: int) -> Panel:
		name = fdt.getprop_or_none(node, 'qcom,mdss-dsi-panel-name')
		return name and Panel(name.as_str(), fdt, node)
Example #9
0
	def __init__(self, name: str, fdt: Fdt2, node: int) -> None:
		self.name = name
		self.id = _remove_before(_remove_prefixes(fdt.get_name(node), 'qcom,mdss_dsi_', 'ss_dsi_panel_', 'mot_').lower(), ',')
		print(f'Parsing: {self.id} ({name})')
		self.short_id = _replace_all(self.id, '_panel', '_video', '_vid', '_cmd',
									 '_hd', '_qhd', '_720p', '_1080p',
									 '_wvga', '_fwvga', '_qvga', '_xga', '_wxga')
		self.h = Dimension(fdt, node, Dimension.Type.HORIZONTAL)
		self.v = Dimension(fdt, node, Dimension.Type.VERTICAL)
		self.framerate = fdt.getprop(node, 'qcom,mdss-dsi-panel-framerate').as_int32()
		self.bpp = fdt.getprop(node, 'qcom,mdss-dsi-bpp').as_int32()
		self.mode = Mode(fdt.getprop(node, 'qcom,mdss-dsi-panel-type').as_str())
		self.traffic_mode = TrafficMode.parse(fdt.getprop(node, 'qcom,mdss-dsi-traffic-mode'))
		backlight = fdt.getprop_or_none(node, 'qcom,mdss-dsi-bl-pmic-control-type')
		self.backlight = BacklightControl(backlight.as_str()) if backlight else None
		self.max_brightness = fdt.getprop_int32(node, 'qcom,mdss-dsi-bl-max-level', None)

		self.lanes = 0
		while fdt.getprop_or_none(node, f'qcom,mdss-dsi-lane-{self.lanes}-state') is not None:
			self.lanes += 1

		self.flags = self.mode.flags + self.traffic_mode.flags

		if fdt.getprop_int32(node, 'qcom,mdss-dsi-h-sync-pulse') != 0:
			self.flags.append('MIPI_DSI_MODE_VIDEO_HSE')

		if fdt.getprop_or_none(node, 'qcom,mdss-dsi-tx-eot-append') is None:
			self.flags.append('MIPI_DSI_MODE_EOT_PACKET')

		if fdt.getprop_or_none(node, 'qcom,mdss-dsi-force-clock-lane-hs') is None \
				and fdt.getprop_or_none(node, 'qcom,mdss-dsi-force-clk-lane-hs') is None:
			self.flags.append('MIPI_DSI_CLOCK_NON_CONTINUOUS')

		reset_seq = fdt.getprop_or_none(node, 'qcom,mdss-dsi-reset-sequence')
		if reset_seq is not None:
			itr = iter(reset_seq.as_uint32_array())
			self.reset_seq = list(zip(itr, itr))
		else:
			self.reset_seq = None

		self.cmds = {
			'on': CommandSequence(fdt, node, 'on'),
			'off': CommandSequence(fdt, node, 'off')
		}

		# If all commands are sent in LPM, add flag globally
		if self.cmds['on'].state == CommandSequence.State.LP_MODE == self.cmds['off'].state:
			self.flags.append('MIPI_DSI_MODE_LPM')

		if self.bpp == 24:
			self.format = 'MIPI_DSI_FMT_RGB888'
		else:
			raise ValueError(f'Unsupported bpp: {self.bpp} (TODO)')

		# Sony </3
		prop = fdt.getprop_or_none(node, 'somc,mdss-phy-size-mm')
		if prop:
			phy_size_mm = prop.as_uint32_array()
			self.h.size = phy_size_mm[0]
			self.v.size = phy_size_mm[1]
    def __init__(self, name: str, fdt: Fdt2, node: int) -> None:
        self.name = name
        self.id = _remove_before(
            _remove_prefixes(fdt.get_name(node), 'qcom,mdss_dsi_',
                             'ss_dsi_panel_', 'mot_').lower(), ',')
        print(f'Parsing: {self.id} ({name})')
        self.short_id = _replace_all(self.id, '_panel', '_video', '_vid',
                                     '_cmd', '_hd', '_qhd', '_720p', '_1080p',
                                     '_wvga', '_fwvga', '_qvga', '_xga',
                                     '_wxga')

        # Newer SoCs can use panels in different modes (resolution, refresh rate etc).
        # We don't support this properly yet but many panels just have a single mode
        # ("timing") defined, so let's try to support this here.
        mode_node = _find_mode_node(fdt, node)
        self.h = Dimension(fdt, node, mode_node, Dimension.Type.HORIZONTAL)
        self.v = Dimension(fdt, node, mode_node, Dimension.Type.VERTICAL)
        self.framerate = fdt.getprop(
            mode_node, 'qcom,mdss-pan-dsi-frame-rate').as_int32()
        self.bpp = fdt.getprop(node, 'qcom,mdss-pan-bpp').as_int32()
        self.mode = Mode(
            'dsi_cmd_mode')  # FIXME, what do to with missing dsi_cmd_mode?
        self.traffic_mode = TrafficMode.parse(
            fdt.getprop(node, 'qcom,mdss-pan-dsi-traffic-mode'))

        backlight = fdt.getprop_or_none(node,
                                        'qcom,mdss-dsi-bl-pmic-control-type')
        self.backlight = BacklightControl(
            backlight.as_str()) if backlight else None
        self.max_brightness = fdt.getprop_int32(node,
                                                'qcom,mdss-dsi-bl-max-level',
                                                None)
        if self.backlight == BacklightControl.DCS and self.max_brightness is None:
            print(
                "WARNING: DCS backlight without maximum brightness, ignoring..."
            )
            self.backlight = None

        self.lanes = 0
        while fdt.getprop_or_none(
                node, f'qcom,mdss-dsi-lane-{self.lanes}-state') is not None:
            self.lanes += 1
        self.lane_map = LaneMap.parse(
            fdt.getprop_or_none(node, 'qcom,mdss-dsi-lane-map'))

        self.flags = self.mode.flags + self.traffic_mode.flags

        if fdt.getprop_int32(node, 'qcom,mdss-dsi-h-sync-pulse') != 0:
            self.flags.append('MIPI_DSI_MODE_VIDEO_HSE')

        if fdt.getprop_or_none(node, 'qcom,mdss-dsi-tx-eot-append') is None:
            self.flags.append('MIPI_DSI_MODE_EOT_PACKET')

        if fdt.getprop_or_none(node, 'qcom,mdss-dsi-force-clock-lane-hs') is None \
          and fdt.getprop_or_none(node, 'qcom,mdss-dsi-force-clk-lane-hs') is None:
            self.flags.append('MIPI_DSI_CLOCK_NON_CONTINUOUS')

        reset_seq = fdt.getprop_or_none(node, 'qcom,mdss-dsi-reset-sequence')
        if reset_seq is not None:
            itr = iter(reset_seq.as_uint32_array())
            self.reset_seq = list(zip(itr, itr))
        else:
            self.reset_seq = None

        self.cmds = {
            'on': CommandSequence(fdt, mode_node, 'on'),
            'off': CommandSequence(fdt, mode_node, 'off')
        }

        # If all commands are sent in LPM, add flag globally
        if self.cmds['on'].state == CommandSequence.State.LP_MODE == self.cmds[
                'off'].state:
            self.flags.append('MIPI_DSI_MODE_LPM')

        if self.bpp == 24:
            self.format = 'MIPI_DSI_FMT_RGB888'
        else:
            raise ValueError(f'Unsupported bpp: {self.bpp} (TODO)')

        # Sony </3
        prop = fdt.getprop_or_none(node, 'somc,mdss-phy-size-mm')
        if prop:
            phy_size_mm = prop.as_uint32_array()
            self.h.size = phy_size_mm[0]
            self.v.size = phy_size_mm[1]
	def __init__(self, name: str, fdt: Fdt2, node: int) -> None:
		self.name = name
		self.node_name = fdt.get_name(node)
		self.id = _remove_before(_remove_prefixes(self.node_name, 'qcom,mdss_dsi_', 'ss_dsi_panel_', 'mot_').lower(), ',')
		print(f'Parsing: {self.id} ({name})')
		self.short_id = _replace_all(self.id, '_panel', '_video', '_vid', '_cmd',
									 '_hd', '_qhd', '_720p', '_1080p',
									 '_wvga', '_fwvga', '_qvga', '_xga', '_wxga')

		# Newer SoCs can use panels in different modes (resolution, refresh rate etc).
		# We don't support this properly yet but many panels just have a single mode
		# ("timing") defined, so let's try to support this here.
		mode_node = _find_mode_node(fdt, node)
		self.h = Dimension(fdt, node, mode_node, Dimension.Type.HORIZONTAL)
		self.v = Dimension(fdt, node, mode_node, Dimension.Type.VERTICAL)
		self.framerate = fdt.getprop(mode_node, 'qcom,mdss-dsi-panel-framerate').as_int32()
		self.bpp = fdt.getprop(node, 'qcom,mdss-dsi-bpp').as_int32()
		self.mode = Mode(fdt.getprop(node, 'qcom,mdss-dsi-panel-type').as_str())
		self.traffic_mode = TrafficMode.parse(fdt.getprop(node, 'qcom,mdss-dsi-traffic-mode'))

		backlight = fdt.getprop_or_none(node, 'qcom,mdss-dsi-bl-pmic-control-type')
		self.backlight = BacklightControl(backlight.as_str()) if backlight else None
		self.max_brightness = fdt.getprop_int32(node, 'qcom,mdss-dsi-bl-max-level', None)
		if self.backlight == BacklightControl.DCS and self.max_brightness is None:
			print("WARNING: DCS backlight without maximum brightness, ignoring...")
			self.backlight = None

		self.lanes = 0
		while fdt.getprop_or_none(node, f'qcom,mdss-dsi-lane-{self.lanes}-state') is not None:
			self.lanes += 1
		self.lane_map = LaneMap.parse(fdt.getprop_or_none(node, 'qcom,mdss-dsi-lane-map'))

		self.flags = self.mode.flags + self.traffic_mode.flags

		if fdt.getprop_int32(node, 'qcom,mdss-dsi-h-sync-pulse') != 0:
			self.flags.append('MIPI_DSI_MODE_VIDEO_HSE')

		if fdt.getprop_or_none(node, 'qcom,mdss-dsi-tx-eot-append') is None:
			self.flags.append('MIPI_DSI_MODE_NO_EOT_PACKET')

		if fdt.getprop_or_none(node, 'qcom,mdss-dsi-force-clock-lane-hs') is None \
				and fdt.getprop_or_none(node, 'qcom,mdss-dsi-force-clk-lane-hs') is None \
				and fdt.getprop_or_none(node, 'qcom,mdss-force-clk-lane-hs') is None:
			self.flags.append('MIPI_DSI_CLOCK_NON_CONTINUOUS')

		reset_seq = fdt.getprop_or_none(node, 'qcom,mdss-dsi-reset-sequence')
		if reset_seq is not None:
			itr = iter(reset_seq.as_uint32_array())
			self.reset_seq = list(zip(itr, itr))
		else:
			self.reset_seq = None

		self.cmds = {
			'on': CommandSequence(fdt, mode_node, 'on'),
			'off': CommandSequence(fdt, mode_node, 'off')
		}

		# If all commands are sent in LPM, add flag globally
		if self.cmds['on'].state == CommandSequence.State.LP_MODE == self.cmds['off'].state:
			self.flags.append('MIPI_DSI_MODE_LPM')

		if self.bpp == 24:
			self.format = 'MIPI_DSI_FMT_RGB888'
		else:
			raise ValueError(f'Unsupported bpp: {self.bpp} (TODO)')

		# Sony </3
		prop = fdt.getprop_or_none(node, 'somc,mdss-phy-size-mm')
		if prop:
			phy_size_mm = prop.as_uint32_array()
			self.h.size = phy_size_mm[0]
			self.v.size = phy_size_mm[1]

		# Check DSI controller if LDO mode is needed
		self.ldo_mode = False
		dsi_ctrl = fdt.getprop_or_none(node, 'qcom,mdss-dsi-panel-controller')
		if dsi_ctrl is not None:
			dsi_ctrl = fdt.node_offset_by_phandle(dsi_ctrl.as_uint32())
			self.ldo_mode = fdt.getprop_or_none(dsi_ctrl, 'qcom,regulator-ldo-mode') is not None

		# Timings are usually calculated by the driver except for downstream and LK
		p = fdt.getprop_or_none(node, 'qcom,mdss-dsi-panel-timings')
		self.timings = bytes(p) if p else bytes()
		self.tclk_post = fdt.getprop_int32(node, 'qcom,mdss-dsi-t-clk-post')
		self.tclk_pre = fdt.getprop_int32(node, 'qcom,mdss-dsi-t-clk-pre')

		# Additional weird values used by downstream and LK
		self.hsync_skew = fdt.getprop_int32(node, 'qcom,mdss-dsi-h-sync-skew')
		self.hfp_power_mode = fdt.getprop_or_none(node, 'qcom,mdss-dsi-hfp-power-mode') is not None
		self.hsa_power_mode = fdt.getprop_or_none(node, 'qcom,mdss-dsi-hsa-power-mode') is not None
		self.hbp_power_mode = fdt.getprop_or_none(node, 'qcom,mdss-dsi-hbp-power-mode') is not None
		self.bllp_power_mode = fdt.getprop_or_none(node, 'qcom,mdss-dsi-bllp-power-mode') is not None
		self.bllp_eof_power_mode = fdt.getprop_or_none(node, 'qcom,mdss-dsi-bllp-eof-power-mode') is not None
		self.lp11_init = fdt.getprop_or_none(node, 'qcom,mdss-dsi-lp11-init') is not None
		self.init_delay = fdt.getprop_int32(node, 'qcom,mdss-dsi-init-delay-us')