<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Ersa's Blog]]></title><description><![CDATA[Android, *nix Engineering ]]></description><link>https://blog.ersa.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 10 Apr 2026 21:48:52 GMT</lastBuildDate><atom:link href="https://blog.ersa.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[From Pixels to Physical Layers: The Architecture of MIPI DSI to LVDS Conversion]]></title><description><![CDATA[1. The Foundations of Display Logic
1.1 Raster timing primitives
A raster display is driven by a continuous stream of pixels accompanied by timing signals that delineate lines and frames. Horizontal s]]></description><link>https://blog.ersa.dev/from-pixels-to-physical-layers-the-architecture-of-mipi-dsi-to-lvds-conversion</link><guid isPermaLink="true">https://blog.ersa.dev/from-pixels-to-physical-layers-the-architecture-of-mipi-dsi-to-lvds-conversion</guid><dc:creator><![CDATA[Gagan M]]></dc:creator><pubDate>Fri, 10 Apr 2026 11:23:02 GMT</pubDate><content:encoded><![CDATA[<h2>1. The Foundations of Display Logic</h2>
<h3>1.1 Raster timing primitives</h3>
<p>A raster display is driven by a continuous stream of pixels accompanied by timing signals that delineate lines and frames. <strong>Horizontal sync (H-Sync)</strong> marks the start of each active line, and <strong>vertical sync (V-Sync)</strong> marks the start of each frame. Between active regions, the controller inserts <strong>front porch</strong>, <strong>back porch</strong>, and sync pulse intervals, which together form the blanking region and define the total pixels per line and total lines per frame. The <strong>pixel clock</strong> is the rate at which pixels are launched toward the panel; the product of total horizontal pixels, total vertical lines, and frame rate equals this clock.[^1]</p>
<p>In many RGB-style interfaces, a <strong>data enable (DE)</strong> signal is asserted only during the active video region of each line, allowing the panel to ignore pixel data during porches and sync pulses. For strictly DE-only panels (no discrete H-Sync/V-Sync pins), line and frame boundaries are inferred from internal timing locked to the pixel clock and DE gating.[^2][^1]</p>
<h3>1.2 Timing relationships and pixel clock formula</h3>
<p>For a given mode, timing is often expressed as:</p>
<ul>
<li><p>Visible pixels per line $$H_{active}$$</p>
</li>
<li><p>Total horizontal blanking (front porch + back porch + H-Sync width) $$H_{blank}$$</p>
</li>
<li><p>Visible lines per frame $$V_{active}$$</p>
</li>
<li><p>Total vertical blanking (front porch + back porch + V-Sync width) $$V_{blank}$$:</p>
</li>
</ul>
<p>The pixel clock is then:</p>
<p>$$f_{clk} = (H_{active} + H_{blank}) \times (V_{active} + V_{blank}) \times \text{FrameRate} \tag{1}$$</p>
<p>This corresponds directly to the HTotal and VTotal definitions used in Qualcomm and other display controller calculations, where $$HTotal = H_{active} + H_{FP} + H_{BP} + H_{Sync}$$ and $$VTotal = V_{active} + V_{FP} + V_{BP} + V_{Sync}$$.[^1]</p>
<h2>1.3 MSM8953 MDSS display path</h2>
<p>On MSM8953, the <strong>Mobile Display Subsystem (MDSS)</strong> comprises an MDP (Mobile Display Processor) that reads from framebuffer, applies blending and scaling, and then drives one or more MIPI DSI controllers which connect to the LCD module. The MDSS is represented in device tree as <code>qcom,mdss_mdp</code> plus one or more <code>qcom,mdss-dsi-ctrl</code> nodes, with clock, regulator, and PHY dependencies explicitly described.[^3][^4]</p>
<p>Panel-specific parameters such as resolution, bpp (RGB888 vs RGB666), porches, and sync widths are carried in a <code>mdss-dsi-panel</code> node, which the DSI driver parses to program both timing and D-PHY characteristics. The MDP generates a raster at the pixel clock computed from equation (1), and the DSI host converts that raster into DSI video packets, including sync events and blanking periods encoded as packets rather than discrete pins.[^5][^6]</p>
<h3>1.4 MDSS DSI host and D-PHY modes</h3>
<p>The MSM8953 DSI controller is a DSI v2-compatible block that sits above a MIPI D-PHY instance. D-PHY provides one high-speed differential clock lane and one to four high-speed differential data lanes, each of which can operate in <strong>high-speed (HS)</strong> or <strong>low-power (LP)</strong> mode. In HS mode, the lanes carry low-swing differential signals up to around 1 Gbps per lane on this class of SoC, while LP mode uses single-ended 1.2 V signaling at much lower data rates for configuration and idle phases.[^4][^7][^8][^9]</p>
<p>On Qualcomm platforms, panel timings (HFP, HBP, HSync, VFP, VBP, VSync) and DSI link parameters (bpp, lane count, non-burst vs burst mode) are encoded in DTSI properties and translated by the MDSS driver into register programming for the DSI host and PHY timing array. Formulas commonly used in the driver mirror the generic relationship: the MIPI serial clock is set high enough to carry the pixel stream across the chosen lanes and bpp, for example $$MipiCLK = HTotal \times VTotal \times FPS \times BPP / (\text{LaneNumber} \times 2)$$ in video mode.[^6][^1]</p>
<h2>2. The MIPI DSI Protocol Stack</h2>
<h3>2.1 Layering model</h3>
<p>MIPI DSI is architected as a layered stack:</p>
<ul>
<li><p><strong>Application layer</strong>: Packs framebuffer pixels and display commands (DCS, vendor commands) into logical transfers, deciding which regions update when.[^10]</p>
</li>
<li><p><strong>Low-level protocol layer</strong>: Frames bytes into <strong>packets</strong> with headers (data type, virtual channel, word count), ECC, CRC, and handles short vs long packets and error reporting.[^7][^10]</p>
</li>
<li><p><strong>PHY layer (D-PHY)</strong>: Implements HS and LP electrical signaling on clock/data lanes, including termination control, HS/LP state machines, and timing of SoT/EoT sequences.[^11][^7]</p>
</li>
</ul>
<p>Host-side, the DSI controller distributes pixel data across 1–4 lanes (lane distribution), while the sink re-merges lanes (lane merging) back into a single byte stream prior to packet decoding.[^10]</p>
<h3>2.2 Packetization of video streams</h3>
<p>In <strong>video mode</strong>, pixel data is sent continuously line by line using long packets whose payloads hold multiple RGB pixels, surrounded by short packets that indicate line start, line end, frame start, and frame end. For RGB888, each pixel contributes 3 bytes to the payload; for RGB666, payload packing may be loosely or tightly packed depending on the configured data type (for example, 0x2E for 18 bpp loosely packed).[^12][^13][^10]</p>
<p>The SN65DSI83 supports RGB888 and RGB666 packet formats and relies on a <strong>line-by-line transfer rule</strong>: DSI line time (sync-to-sync) must match the LVDS line time, ensuring that its internal buffers neither overrun nor underflow while streaming.[^14][^15]</p>
<h3>2.3 D-PHY electrical signaling: VOD and VCM</h3>
<p>D-PHY defines HS signaling as a low-swing differential pair with output differential voltage $$V_{OD}$$ and common-mode voltage $$V_{CM}$$.[^16][^11]</p>
<ul>
<li><p><strong>HS differential swing</strong>: HS transmitters produce $$V_{OD}$$ in the range of roughly 140–270 mV (single-ended differential, corresponding to 280–540 mV peak-to-peak) at data rates from about 80 Mb/s up to multiple Gbps, depending on the D-PHY version.[^7][^16]</p>
</li>
<li><p><strong>HS common-mode</strong>: The HS common-mode at the receiver is kept in the range of roughly 70–330 mV DC, allowing AC-coupled or on-die-terminated receivers with specified common-mode capacitance.[^17]</p>
</li>
</ul>
<p>The differential voltage is defined as $$V_{OD} = V_{DP} - V_{DN}$$, where $$V_{DP}$$ and $$V_{DN}$$ are the instantaneous voltages on the positive and negative HS pins. HS-1 and HS-0 states correspond to positive and negative $$V_{OD}$$, and the receiver detects transitions between these states at the center of the unit interval. In LP mode, the same wires are used as unterminated single-ended lines switching around 1.2 V, trading speed for low power and simplicity of command transactions.[^8][^16][^7]</p>
<h2>3. LVDS Mechanics and Signal Physics</h2>
<h3>3.1 Current-steering driver model</h3>
<p><strong>Low Voltage Differential Signaling (LVDS)</strong> is defined as a current-mode differential standard in ANSI/TIA/EIA-644, optimized for several hundred Mb/s per pair with low power and high noise immunity. A typical LVDS transmitter implements roughly a 3.5 mA constant current source steered between the two output pins; with a 100 Ω differential termination at the receiver, this produces a nominal differential swing of about 350 mV.[^18][^19][^20]</p>
<p>Because the receiver input is high impedance, almost all of the driver current flows through the termination resistor, yielding the differential voltage:</p>
<p>$$V_{diff} \approx I_{driver} \times R_{term} = 3.5,\text{mA} \times 100,\Omega \approx 350,\text{mV} \tag{2}$$</p>
<p>LVDS threshold levels are typically specified at about 100 mV, leaving comfortable margin for attenuation and noise while still guaranteeing correct detection of logical high vs low states.[^20][^18]</p>
<h3>3.2 Common-mode and impedance environment</h3>
<p>LVDS common-mode input range is wide (roughly 0.05–2.35 V for many devices), allowing operation across different supply voltages and simplifying level compatibility between 1.8 V, 2.5 V, and 3.3 V devices. Transmission lines and terminations are designed for about 100 Ω differential impedance with 50 Ω odd-mode, which matches the internal driver and receiver impedance and minimizes reflections.[^21][^22][^2][^20]</p>
<p>The termination is most often a single 100 Ω resistor placed as close as possible to the receiver pins, completing the current loop and matching the differential impedance of the PCB or cable. For on-board links, traces are typically routed as tightly coupled differential pairs over a solid reference plane to achieve the desired impedance.[^22][^23][^21]</p>
<h3>3.3 Noise immunity and distance capability</h3>
<p>Differential signaling inherently cancels common-mode noise because interference that couples equally into both conductors is subtracted at the receiver. LVDS’ low swing reduces di/dt and radiated emissions while still providing eye openings adequate for hundreds of megabits per second to multiple gigabits per second over copper traces or twisted-pair cables.[^18][^20]</p>
<p>Compared with CMOS/TTL single-ended voltage-mode drivers, LVDS’ constant current behavior and termination matching reduce reflections and ground bounce, enabling longer distances and higher data rates on the same medium. The combination of low swing, controlled impedance, and differential routing ensures high signal integrity even in noisy environments.[^24][^18]</p>
<h2>4. The SN65DSI83 Bridge: Deserialization and Reserialization</h2>
<h3>4.1 High-level function</h3>
<p>The <strong>SN65DSI83</strong> is a single-channel MIPI DSI to single-link FlatLink LVDS bridge that accepts up to four D-PHY data lanes plus a D-PHY clock and outputs four LVDS data pairs plus one LVDS clock pair. It supports 18 bpp RGB666 and 24 bpp RGB888 DSI video packets and can drive LVDS pixel clocks from 25 MHz to 154 MHz, enabling resolutions up to 1920 × 1200 at 60 Hz with reduced blanking or 1366 × 768 / 1280 × 800 at 60 Hz.[^14][^12]</p>
<p>Internally, the device implements a D-PHY receiver, a DSI packet engine, line buffering, and a FlatLink LVDS serializer with programmable mapping and timing. It is configured over I²C (local control interface) using a set of control and status registers (CSRs), often computed by TI’s DSI-Tuner tool.[^15][^12]</p>
<h3>4.2 Deserialization pipeline from DSI</h3>
<p>On the input side, the D-PHY block receives HS and LP traffic on up to four data lanes and one clock lane, managing terminations and HS/LP transitions. DSI bytes are distributed across lanes and reassembled by a <strong>lane-merge unit</strong>, which handles various lane counts (1–4) and supports cases where packet length is not a multiple of the lane count.[^12][^7]</p>
<p>The packet processor detects Start-of-Transmission (SoT) / End-of-Transmission (EoT) sequences, decodes packet headers, checks ECC and CRC, and extracts pixel payloads from RGB666 or RGB888 long packets. The device discards non-video packets that are not needed for the LVDS side and converts the continuous stream of pixels into a raster aligned with HSYNC, VSYNC, and DE.[^12]</p>
<h3>4.3 Reserialization pipeline to LVDS</h3>
<p>On the output side, SN65DSI83’s <strong>channel formatter and LVDS serializer</strong> map the internal pixel bus and control signals (HS, VS, DE) into FlatLink-style LVDS data streams. Each LVDS data pair (A_Y0–A_Y3) carries seven serialized bits per pixel clock, while the LVDS clock pair (A_CLKP/N) toggles at the pixel rate.[^12]</p>
<p>LVDS output formats are controlled via CSRs (for example, CHA_24BPP_FORMAT1 and CHA_24BPP_MODE at 0x18), which determine how 18 bpp vs 24 bpp data and JEIDA-like vs VESA-like mapping are realized. The device also supports optional LVDS test patterns for panel or link bring-up, generated entirely on the LVDS side without DSI input.[^12]</p>
<h3>4.4 Clock management and PLL</h3>
<p>SN65DSI83’s LVDS clock can be derived from either the DSI channel A HS clock or an external reference clock (REFCLK).[^15][^12]</p>
<ul>
<li><p>When <strong>DSI clock</strong> is selected, the LVDS clock is generated by dividing the DSI bit clock by a programmable factor in <code>DSI_CLK_DIVIDER</code> (CSR 0x0B.7:3).[^15]</p>
</li>
<li><p>When <strong>REFCLK</strong> is selected, an external clock (25–154 MHz) is multiplied by <code>REFCLK_MULTIPLIER</code> (CSR 0x0B.1:0) to generate the LVDS clock.[^15][^12]</p>
</li>
</ul>
<p>Additional CSRs such as <code>LVDS_CLK_RANGE</code> and <code>CH_DSI_CLK_RANGE</code> must be set to inform the internal PLL about the expected frequency ranges for correct lock behavior. After CSRs are programmed, the <code>PLL_EN</code> bit (0x0D.0) is asserted to enable the PLL, and software typically waits on the <code>PLL_LOCK</code> status bit (0x0A.7) before soft-resetting the video path.[^15][^12]</p>
<h3>4.5 Latency and buffering considerations</h3>
<p>The SN65DSI83 operates on a <strong>line-based buffering rule</strong>: DSI input line time must match LVDS output line time, even though individual porch and sync fields may differ between the two sides. Internal partial line buffers absorb short-term burstiness—especially in DSI burst mode—but are not large enough to compensate for arbitrary mismatches in line time or sustained underflow/overflow.[^14][^15]</p>
<p>Because of this, the DSI-Tuner tool calculates minimum DSI clock requirements and line times based on the LVDS panel parameters, ensuring that DSI throughput and timing are sufficient to maintain a full FIFO for each outgoing line. Latency through the bridge is therefore primarily on the order of a fraction of a line to a few lines, but correct configuration is essential to avoid dropped lines, frame tearing, or visible artifacts.[^15]</p>
<h2>5. Visual Architecture and Data Flow</h2>
<h3>5.1 System-level signal path</h3>
<p>A typical MSM8953 to LVDS panel chain via SN65DSI83 can be represented as:</p>
<img src="https://mermaid.ink/svg/Zmxvd2NoYXJ0IExSCiAgICBzdWJncmFwaCBNU004OTUzWyJNU004OTUzIFNvQyAoTURQICsgRFNJKSJdCiAgICAgICAgRFNJX0NUUkxbIkRTSSBIb3N0IEN0cmwiXQogICAgICAgIERQSFlfVFhbIkQtUEhZIFRYIExhbmVzIl0KICAgICAgICBEU0lfQ1RSTCAtLSAiUGFyYWxsZWwgcGl4ZWwgYnVzPGJyLz5IU1lOQyAvIFZTWU5DIC8gREUiIC0tPiBEUEhZX1RYCiAgICBlbmQKICAgIAogICAgc3ViZ3JhcGggU042NURTSTgzWyJTTjY1RFNJODMgRFNJLXRvLUxWRFMiXQogICAgICAgIERQSFlfUlhbIkQtUEhZIFJYIExhbmVzIl0KICAgICAgICBMVkRTX1RYWyJMVkRTIFR4IFBhaXJzIl0KICAgICAgICBEUEhZX1JYIC0tPiBMVkRTX1RYCiAgICBlbmQKICAgIAogICAgc3ViZ3JhcGggUGFuZWxbIkxWRFMgUGFuZWwgKFJHQiBpbnRlcmZhY2UpIl0KICAgICAgICBUQ09OWyJUQ09OIC8gQ29sdW1uIERyaXZlcnMiXQogICAgZW5kCgogICAgRFBIWV9UWCAtLSAiRFNJIENMSy9EQTAuLkRBMzxici8+KEhTL0xQKSIgLS0+IERQSFlfUlgKICAgIExWRFNfVFggLS0gIkxWRFMgQ0xLIC8gQV9ZMC4uWTMiIC0tPiBUQ09OCg==?bgColor=333333&amp;theme=dark" alt="System-level signal path flowchart" style="display:block;margin:0 auto" />

<p>The SoC’s DSI host controller packetizes pixel data and drives it through its D-PHY transmitter in HS mode during active video while using LP mode for blanking and command sequences. SN65DSI83 receives and decodes this stream, then reserializes it to LVDS for the panel’s timing controller (TCON).[^1][^7][^14][^12]</p>
<h3>5.2 Internal bridge stages</h3>
<p>Internally, SN65DSI83 can be visualized as:</p>
<img src="https://mermaid.ink/svg/Zmxvd2NoYXJ0IExSCiAgICBzdWJncmFwaCBEU0lfU2lkZSBbIkRTSSBTaWRlIChJbnB1dCkiXQogICAgICAgIFJYWyJELVBIWSBSWCAoSFMvTFApPGJyLz7igKIgVGVybWluYXRpb24gY3RybDxici8+4oCiIEhTIC8gTFAgc3RhdGUiXQogICAgZW5kCiAgICAKICAgIHN1YmdyYXBoIEludGVybmFsIFsiSW50ZXJuYWwgTG9naWMiXQogICAgICAgIFBFWyJEU0kgUGFja2V0IEVuZ2luZTxici8+4oCiIExhbmUgbWVyZ2U8YnIvPuKAoiBWaWRlbyBwYWNrZXQgZGVjLjxici8+4oCiIEZJRk8gLyBsaW5lIGJ1ZiJdCiAgICBlbmQKICAgIAogICAgc3ViZ3JhcGggTFZEU19TaWRlIFsiTFZEUyBTaWRlIChPdXRwdXQpIl0KICAgICAgICBTRVJbIkxWRFMgU2VyaWFsaXplcjxici8+KyBDaGFubmVsIEZvcm1hdHRlcjxici8+KyBMVkRTIFBMTCAvIENsb2NrPGJyLz4rIE91dHB1dCBkcml2ZXJzIl0KICAgIGVuZAogICAgCiAgICBSWCAtLSAiYnl0ZSBsYW5lcyIgLS0+IFBFCiAgICBQRSAtLSAicGl4ZWxzIDxici8+JiBjdHJsIiAtLT4gU0VSCgogICAgSTJDKCgiScKyQyAoQ1NScykiKSkgLS0+IFBFCiAgICBQRSAtLT4gVGltaW5nKCgiVGltaW5nIikpCg==?bgColor=333333&amp;theme=dark" alt="Internal bridge stages flowchart" style="display:block;margin:0 auto" />

<p>The <strong>D-PHY RX</strong> brings HS/LP currents and voltages into the device, performs HS differential termination and LP single-ended sensing, and converts symbols into aligned bytes. The <strong>packet engine</strong> reassembles packets, extracts video payloads using RGB666/RGB888 formatting rules, and writes pixels into <strong>line buffers</strong>. The LVDS side comprises a PLL-based clock generator, the <strong>channel formatter</strong> implementing JEIDA/VESA-like bit mapping, and current-mode LVDS drivers.[^7][^12]</p>
<h2>6. Signal Mapping and Protocol Tables</h2>
<h3>6.1 LVDS mapping: VESA vs JEIDA style</h3>
<p>The SN65DSI83 datasheet defines two 24-bpp LVDS mapping formats (Format 1 and Format 2), which correspond closely to the commonly termed <strong>VESA</strong> and <strong>JEIDA</strong> schemes used by many panels.[^25][^12]</p>
<p>For a 24-bit RGB pixel with bits R7..R0, G7..G0, B7..B0 and control signals HS, VS, DE, the mappings per pixel clock are:</p>
<h4>Format 2 (JEIDA-like): MSBs on fourth lane</h4>
<p>From the SN65DSI83 FlatLink output diagram for Single-Link 24 bpp Format 2:[^12]</p>
<ul>
<li><p>A_Y0P/N: R2 R1 R0 R3 R4 R5 G0</p>
</li>
<li><p>A_Y1P/N: G3 G2 G1 G4 G5 B0 B1</p>
</li>
<li><p>A_Y2P/N: B4 B3 B2 B5 HS VS DE</p>
</li>
<li><p>A_Y3P/N: G6 R7 R6 G7 B6 B7 0</p>
</li>
</ul>
<p>This can be represented as a table of bit positions per LVDS data pair and serial time slot $$T_0..T_6$$:</p>
<table>
<thead>
<tr>
<th>LVDS Pair</th>
<th>T0</th>
<th>T1</th>
<th>T2</th>
<th>T3</th>
<th>T4</th>
<th>T5</th>
<th>T6</th>
</tr>
</thead>
<tbody><tr>
<td>A_Y0</td>
<td>R2</td>
<td>R1</td>
<td>R0</td>
<td>R3</td>
<td>R4</td>
<td>R5</td>
<td>G0</td>
</tr>
<tr>
<td>A_Y1</td>
<td>G3</td>
<td>G2</td>
<td>G1</td>
<td>G4</td>
<td>G5</td>
<td>B0</td>
<td>B1</td>
</tr>
<tr>
<td>A_Y2</td>
<td>B4</td>
<td>B3</td>
<td>B2</td>
<td>B5</td>
<td>HS</td>
<td>VS</td>
<td>DE</td>
</tr>
<tr>
<td>A_Y3</td>
<td>G6</td>
<td>R7</td>
<td>R6</td>
<td>G7</td>
<td>B6</td>
<td>B7</td>
<td>0</td>
</tr>
</tbody></table>
<p>This style places the <strong>most significant bits (MSBs)</strong> of each color (R7, G7, B7) plus some upper bits on the fourth LVDS data pair, which matches JEIDA conventions for 24-bit mapping where the extra lane carries the MSBs for compatibility with 18-bit modes.[^25]</p>
<h4>Format 1 (VESA-like): LSBs on fourth lane</h4>
<p>For Format 1, the SN65DSI83 datasheet shows:[^12]</p>
<ul>
<li><p>A_Y0P/N: R4 R3 R2 R5 R6 R7 G2</p>
</li>
<li><p>A_Y1P/N: G5 G4 G3 G6 G7 B2 B3</p>
</li>
<li><p>A_Y2P/N: B6 B5 B4 B7 HS VS DE</p>
</li>
<li><p>A_Y3P/N: G0 R1 R0 G1 B0 B1 0</p>
</li>
</ul>
<p>The corresponding mapping table is:</p>
<table>
<thead>
<tr>
<th>LVDS Pair</th>
<th>T0</th>
<th>T1</th>
<th>T2</th>
<th>T3</th>
<th>T4</th>
<th>T5</th>
<th>T6</th>
</tr>
</thead>
<tbody><tr>
<td>A_Y0</td>
<td>R4</td>
<td>R3</td>
<td>R2</td>
<td>R5</td>
<td>R6</td>
<td>R7</td>
<td>G2</td>
</tr>
<tr>
<td>A_Y1</td>
<td>G5</td>
<td>G4</td>
<td>G3</td>
<td>G6</td>
<td>G7</td>
<td>B2</td>
<td>B3</td>
</tr>
<tr>
<td>A_Y2</td>
<td>B6</td>
<td>B5</td>
<td>B4</td>
<td>B7</td>
<td>HS</td>
<td>VS</td>
<td>DE</td>
</tr>
<tr>
<td>A_Y3</td>
<td>G0</td>
<td>R1</td>
<td>R0</td>
<td>G1</td>
<td>B0</td>
<td>B1</td>
<td>0</td>
</tr>
</tbody></table>
<p>Here the <strong>least significant bits (LSBs)</strong> R0, G0, B0 and some next-less-significant bits reside on the fourth LVDS pair, which aligns with the common VESA mapping used by many notebook panels. SN65DSI83 selects between these via <code>CHA_24BPP_FORMAT1</code> (0x18.1), while <code>CHA_24BPP_MODE</code> (0x18.3) controls 24→18 bpp down-mapping and Y3 lane usage.[^25][^12]</p>
<h3>6.2 DSI pixel rate vs LVDS pixel clock</h3>
<p>The SN65DSI8x video configuration guide provides generic formulas relating DSI throughput and LVDS pixel rate.[^15]</p>
<p>Let:</p>
<ul>
<li><p>$$f_{DSI}$$: DSI bit clock (MHz) per lane</p>
</li>
<li><p>$$N_{lanes}$$: number of active DSI data lanes</p>
</li>
<li><p>$$BPP$$: bits per pixel (18 or 24)</p>
</li>
<li><p>$$f_{LVDS}$$: LVDS pixel clock (MHz)</p>
</li>
</ul>
<p>Then the <strong>DSI pixel rate</strong> in pixels per second is:</p>
<p>$$f_{DSI\pix} = \frac{f{DSI} \times 2 \times N_{lanes}}{BPP} \tag{3}$$</p>
<p>The LVDS pixel rate is essentially the LVDS output clock, determined from the selected source and divider/multiplier network:</p>
<p>$$f_{LVDS} = f_{LVDS_CLK} \tag{4}$$</p>
<p>where $$f_{LVDS_CLK}$$ is computed from either:</p>
<p>$$f_{LVDS\CLK} = \frac{f{DSI}}{D_{DSI}} \quad \text{or} \quad f_{LVDS\CLK} = f{REFCLK} \times M_{REF} \tag{5}$$</p>
<p>with $$D_{DSI}$$ the DSI clock divider (CSR 0x0B.7:3) and $$M_{REF}$$ the reference clock multiplier (CSR 0x0B.1:0).[^15]</p>
<p>For correct operation, line time must match between DSI and LVDS:</p>
<p>$$T_{line} = \frac{HTotal}{f_{LVDS}} = \frac{\text{LineBits}{DSI}}{f{DSI} \times 2 \times N_{lanes}} \tag{6}$$</p>
<p>and the DSI-Tuner tool uses these relationships to compute minimum $$f_{DSI}$$ and valid divider/multiplier combinations.[^15]</p>
<h3>6.3 Pixel clock and video timing</h3>
<p>The LVDS pixel clock for a given resolution and refresh rate is given by equation (1):</p>
<p>$$f_{clk} = (H_{active} + H_{blank}) \times (V_{active} + V_{blank}) \times \text{FrameRate} \tag{1 revisited}$$</p>
<p>This relationship is consistent with both generic LCD timing literature and TI’s throughput calculations, where total throughput is $$(\text{pixels per line}) \times (\text{lines per frame}) \times (\text{frames per second}) \times BPP$$. Using reduced-blanking VESA modes can substantially lower $$H_{blank}$$ and $$V_{blank}$$, reducing both $$f_{clk}$$ and required DSI bandwidth for a given resolution.[^1][^15]</p>
<h2>7. Practical Implementation and Debugging</h2>
<h3>7.1 PCB layout for differential pairs</h3>
<p>For <strong>MIPI DSI</strong> between MSM8953 and SN65DSI83, many practical layout guides recommend routing differential pairs with about 90 Ω differential impedance and 50 Ω single-ended, with tight length matching and no stubs. The D-PHY electrical spec itself expects an 80–125 Ω HS input impedance at the receiver, so 90–100 Ω PCB targets are appropriate for most boards.[^26][^27][^28][^17]</p>
<p>For <strong>LVDS</strong> between SN65DSI83 and the panel, traces and terminations should be designed for 100 Ω differential impedance, matching both ANSI/TIA/EIA-644 and TI’s hardware design guide for SN65DSI83/84/85, which explicitly calls for 100 Ω controlled impedance on both DSI and LVDS differential pairs and a single 100 Ω resistor across each LVDS pair at the receiver.[^29][^23][^22]</p>
<p>General high-speed rules apply on both sides: route pairs over continuous reference planes, avoid crossing splits, keep intra-pair skew below a few mils, minimize via count, and maintain at least three times the trace width spacing to unrelated high-speed nets.[^28][^29]</p>
<h3>7.2 Common failure points in DSI-to-LVDS conversion</h3>
<p>Several recurring issues cause non-functional or unstable MSM8953→SN65DSI83→LVDS panel links:</p>
<ul>
<li><p><strong>PLL not locked</strong>: If <code>LVDS_CLK_RANGE</code>, <code>CH_DSI_CLK_RANGE</code>, and divider/multiplier settings are incorrect, or the DSI clock source is not continuous in HS, the internal PLL may not lock (<code>PLL_LOCK</code> bit remains low), preventing stable LVDS output.[^12][^15]</p>
</li>
<li><p><strong>Initialization sequence errors</strong>: TI specifies a strict init sequence for EN, CSR programming, <code>PLL_EN</code>, and <code>SOFT_RESET</code>; skipping delays or enabling video before PLL lock can result in no video or intermittent output.[^12]</p>
</li>
<li><p><strong>DSI timing mismatch</strong>: If DSI line time does not match LVDS line time, the internal FIFO can underflow or overflow, leading to missing lines, jittery HSYNC/VSYNC, or repeated lines.[^15]</p>
</li>
<li><p><strong>Incorrect bpp or lane configuration</strong>: Mismatches between MSM8953’s configured bpp/lane-count and SN65DSI83 CSRs (for example, DSI expects 4 lanes RGB888 while the bridge is configured for fewer lanes or different packing) prevent correct packet decoding.[^14][^15]</p>
</li>
<li><p><strong>LVDS mapping mismatch (JEIDA vs VESA)</strong>: If the panel expects one mapping and SN65DSI83 is configured for the other, symptoms include color inversion, swapped channels, or bit-shifted color gradients (e.g., banding from LSB/MSB confusion).[^30][^25]</p>
</li>
<li><p><strong>I²C initialization mistakes</strong>: Incorrect target address configuration (ADDR pin) or missing configuration writes to CSRs (notably 0x18–0x25 region for timing and format) will leave the bridge in default state with no valid video, even if DSI input appears correct.[^31][^12]</p>
</li>
<li><p><strong>Signal integrity problems</strong>: Poor differential routing, impedance discontinuities, or excessive skew can close the DSI or LVDS eye, particularly at higher resolutions where DSI clock approaches the upper end of the PHY capability.[^2][^29]</p>
</li>
</ul>
<h3>7.3 Debugging strategy</h3>
<p>A practical bring-up strategy for MSM8953 plus SN65DSI83 includes:</p>
<ul>
<li><p><strong>Validate panel timing and mapping</strong> using the panel datasheet (resolution, refresh, porches, H/V polarity, LVDS mapping) and encode them into both MSM8953 DT and SN65DSI83 CSRs (e.g., <code>CHA_*</code> timing registers, mapping format bits).[^12][^15]</p>
</li>
<li><p><strong>Cross-check DSI and LVDS clocks</strong>: Use the DSI-Tuner tool to compute the required DSI clock, LVDS clock, and CSR settings; validate that MSM8953’s DSI clock and lane configuration match the tool’s assumptions.[^15]</p>
</li>
<li><p><strong>Check PLL status and error registers</strong>: Confirm <code>PLL_LOCK</code> is high and read error registers at 0xE5/0xE6; TI’s video configuration guide describes how to interpret and clear these flags.[^15]</p>
</li>
<li><p><strong>Use LVDS test patterns</strong>: Enable the SN65DSI83 internal pattern generator (CHA_TEST_PATTERN at 0x3C) to confirm that LVDS routing and panel connectivity are good, independent of the DSI side.[^12]</p>
</li>
<li><p><strong>Instrument HS/LP states</strong>: Probe DSI clock and data lanes with a high-bandwidth scope using differential probes to verify correct HS amplitudes, LP voltages, and SoT/EoT structures at the SN65DSI83 input.[^16][^7]</p>
</li>
</ul>
<p>Taken together, understanding the full path from MDSS pixel generation, through DSI packetization and D-PHY signaling, across the SN65DSI83 deserialization/reserialization pipeline, and into LVDS physics enables systematic analysis of failures and optimization of high-speed display links.</p>
<hr />
<h2>References</h2>
<ol>
<li><p><a href="https://blog.csdn.net/qq_40405527/article/details/123043088">Android Qcom Display学习(一)_qcom,mdss-dsi-panel-phy- ...</a> - D- PHY的物理层支持HS( High Speed )和LP( Low Power )两种工作模式HS ... dsi控制器的句柄qcom,mdss-d... 继续访问. DSI PA...</p>
</li>
<li><p><a href="https://resources.altium.com/p/some-lvds-pcb-layout-guidelines-for-ensuring-signal-integrity">LVDS PCB Layout Guidelines for Ensuring Signal Integrity</a> - The swing across the 100 Ohm termination resistor is 350 mV, although one should note a different im...</p>
</li>
<li><p><a href="https://blog.csdn.net/cjianeng/article/details/122756807">高通平台msm8953 display子系统学习</a> - 文章浏览阅读6.7k次，点赞6次，收藏37次。硬件上，高通平台有一个mipi-dsi接口连接LCM，由MDP（mobile display processor）进行管理，就是一般说的LCD控制器软件上...</p>
</li>
<li><p><a href="https://www.kernel.org/doc/Documentation/devicetree/bindings/display/msm/dsi.txt">dsi.txt</a></p>
</li>
<li><p><a href="https://android.googlesource.com/kernel/msm/+/android-wear-5.0.2_r0.1/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt">Git at Google</a></p>
</li>
<li><p><a href="https://android.googlesource.com/kernel/msm/+/android-7.1.0_r0.2/Documentation/devicetree/bindings/fb/mdss-dsi-panel.txt">Git at Google</a></p>
</li>
<li><p><a href="https://download.tek.com/document/61W_25772_0_HR.pdf">[PDF] Understanding and Performing MIPI® D-PHY Physical Layer, CSI ...</a></p>
</li>
<li><p><a href="https://huiminee.wordpress.com/2016/07/27/some-research-on-mipi-csi-2-and-d-phy/">Some Research On MIPI CSI-2 and D-PHY - huiminEE</a> - Depending on the application, the HS mode may be utilized at all times or the D-PHY can switch from ...</p>
</li>
<li><p><a href="https://www.xilinx.com/support/documents/ip_documentation/mipi_dphy/v4_1/pg202-mipi-dphy.pdf">MIPI D-PHY v4.1 LogiCORE IP Product Guide</a> - The HS mode PPI signals can also be used to monitor the HS data transfer. Each txrequesths is counte...</p>
</li>
<li><p><a href="http://weike-iot.com:2211/ebooks/mipi/Connect-with-Experts-MIPI-Interface-Overview-Sld.pdf">mipi dsi/d-phy/csi-2 interfaces</a></p>
</li>
<li><p><a href="https://www.zhuoxunweihong.com/wp-content/uploads/2022/08/mipi_D-PHY_specification_v1-1.pdf">MIPI Alliance Specification for D-PHY</a> - Figure 37 Example HS Transmitter. 1327. The differential output voltage VOD is defined as the differ...</p>
</li>
<li><p><a href="https://www.ti.com/lit/ds/symlink/sn65dsi83.pdf">[PDF] SN65DSI83 MIPI DSI Bridge to FLAT LINK LVDS Single Channel ...</a> - Table 7-3 clarifies the SN65DSI83 device target address. Table 7-3. SN65DSI83 I2C Target Address Des...</p>
</li>
<li><p><a href="http://master.weike-iot.com:2211/ebooks/mipi/Connect-with-Experts-MIPI-Interface-Overview-Sld.pdf">MIPI DSI/D-PHY/CSI-2 INTERFACES - master.weike-iot.com:2211</a></p>
</li>
<li><p><a href="https://www.mouser.com/new/texas-instruments/ti-sn65dsi83-dsi-to-lvds-bridge/">SN65DSI83/SN65DSI83-Q1 DSI-to-LVDS Bridge - TI | Mouser</a> - Texas Instruments SN65DSI83/SN65DSI83-Q1 DSI-to-LVDS Bridge features a single-channel MIPI D-PHY rec...</p>
</li>
<li><p><a href="https://www.ti.com/lit/pdf/slla332">[PDF] SN65DSI8x Video Configuration Guide and ... - Texas Instruments</a> - This document contains information for configuring the SN65DSI83, SN65DSI84, and SN65DSI85 devices c...</p>
</li>
<li><p><a href="https://download.tek.com/manual/MIPI-D_PHY-Measurements-Setup-Library-MOI-DPOJET-EN-US.pdf">MIPI® D-PHY Measurements &amp; Setup Library ...</a> - The D-PHY Specification states, “The differential output voltage VOD is defined as the difference of...</p>
</li>
<li><p><a href="https://www.mipi.org/hubfs/Bangaloe-Synopsys-Enabling-Higher-Data-Rates-1.pdf">B T5 16-15 Synopsys Enabling Higher Data Rates</a> - Higher data rate. • Adaption to newer technologies. • Longer channel length, channel evolution. • Ba...</p>
</li>
<li><p><a href="https://www.ti.com/lit/ug/snla187/snla187.pdf">LVDS Owner's Manual Design Guide, 4th Edition</a> - LVPECL and CML I/O characteristics and termination schemes can vary from one ... LVDS) are popular e...</p>
</li>
<li><p><a href="https://web.pa.msu.edu/hep/d0/ftp/run2b/l1cal/hardware/component_information/national_lvds_owners_manual.pdf">LVDS Owner's Manual</a> - The basic receiver has high DC input impedance, so the majority of driver current flows across the 1...</p>
</li>
<li><p><a href="https://www.doeeet.com/content/application/space-industry/low-voltage-differential-signaling-lvds-overview/">An overview of Low Voltage Differential Signaling (LVDS)</a> - Electrical Characteristics ... Given the 3.5 mA of current through the 100 Ω termination resistor, t...</p>
</li>
<li><p><a href="https://www.mouser.com/pdfDocs/lvdsclocksandtermination.pdf">LVDS Clocks and Termination</a> - Termination of specification compliant LVDS devices is simple. The termination network is a single 1...</p>
</li>
<li><p><a href="https://resources.altium.com/p/eliminate-crosstalk-lvds-routing-and-art-differential-signaling">LVDS Routing and the Art of Differential Signaling</a> - LVDS links require a 100 Ohms differential impedance (50 Ohms odd-mode); For LVDS links confined to ...</p>
</li>
<li><p><a href="https://www.ipcb.com/news/4640.html">LVDS high-speed signal PCB wiring requirements</a> - LVDS has built-in 100 ohm matching, the differential line impedance is controlled at about 100 ohms,...</p>
</li>
<li><p><a href="https://resources.pcb.cadence.com/blog/2023-the-lvds-interface">The LVDS Interface | Advanced PCB Design Blog</a> - Differential Impedance: One of LVDS's critical characteristics is its high differential impedance, t...</p>
</li>
<li><p><a href="https://www.youtube.com/watch?v=GoB35XEv6k8">How Jeida &amp; Vesa LVDS Format Works? - Pixel Fault</a> - The format defines how the RGB pixel bits are packed into LVDS serial data lanes. JEIDA vs. VESA — T...</p>
</li>
<li><p><a href="https://rockchip.fr/RK312X%20TRM/chapter-46-mipi-d-phy.pdf">Chapter 46 MIPI D-PHY 46.1 Overview 46.2 Block Diagram</a> - The MIPI D-PHY transceiver is designed to reliably transmit HS and LP/ULP data/clock over the channe...</p>
</li>
<li><p><a href="https://pcbartists.com/design/pcb-design/mipi-dsi-pcb-layout-notes/">MIPI DSI PCB Layout Notes</a> - Some useful MIPI DSI PCB layout notes, guidelines and tips for MIPI DSI systems. Applicable to MCUs ...</p>
</li>
<li><p><a href="https://pcbartists.com/design/pcb-design/mipi-dsi-pcb-layout-notes/amp/">MIPI DSI PCB Layout Notes - PCB Artists</a> - Some useful MIPI DSI PCB layout notes, guidelines and tips for MIPI DSI systems. Applicable to MCUs ...</p>
</li>
<li><p><a href="https://www.ti.com/lit/pdf/slla340">SN65DSI83, SN65DSI84, and SN65DSI85 Hardware ...</a> - DA<em>P/N and DB</em>P/N pairs should be routed together with controlled-differential 100-Ω impedance. Keep...</p>
</li>
<li><p><a href="https://www.youtube.com/watch?v=w3fY_Mf2YiA">Configuring the SN65DSI8x for single-channel DSI to ...</a> - This video will provide a step-by-step guide on how to configure the DSi devices for a single channe...</p>
</li>
<li><p><a href="https://www.ti.com/lit/pdf/sllu221">[PDF] SN65DSI83, SN65DSI84, and SN65DSI85 EVM User's Manual and ...</a> - Connect J2 and J5 via an SGC-type cable with one-to-one pin mapping to a panel using the I-PEX20455-...</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Technical Deep Dive: Unisoc BSL Protocol, FDL1 and FDL2]]></title><description><![CDATA[The Boot Sequence: Power-On to FDL2
When a Unisoc device (like the SL8541E) powers on, the primary CPU executes code from the primitive ROM (BootROM).
Stage 0: BootROM (BROM)
At power-on, a Unisoc SoC]]></description><link>https://blog.ersa.dev/technical-deep-dive-unisoc-bsl-protocol-fdl1-and-fdl2</link><guid isPermaLink="true">https://blog.ersa.dev/technical-deep-dive-unisoc-bsl-protocol-fdl1-and-fdl2</guid><dc:creator><![CDATA[Gagan M]]></dc:creator><pubDate>Mon, 23 Mar 2026 08:39:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69660cc183a72e6c71493989/84bd0739-8dc0-4844-9e89-1c8fec10c1cf.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>The Boot Sequence: Power-On to FDL2</strong></h2>
<p>When a Unisoc device (like the SL8541E) powers on, the primary CPU executes code from the primitive <strong>ROM (BootROM)</strong>.</p>
<h3><strong>Stage 0: BootROM (BROM)</strong></h3>
<p>At power-on, a Unisoc SoC is an "empty shell" running primitive code from a tiny on-chip ROM. To interact with it, we must catch it in <strong>Download Mode</strong>.</p>
<p>If the device detects a specific key combo (usually Vol-Down) or if the eMMC is blank/corrupted, it enters <strong>Download Mode</strong>. In this state, it enumerates on USB as a Serial Port (VID <code>0x1782</code>, PID <code>0x4D00</code>).</p>
<h3><strong>Stage 1: The Handshake</strong></h3>
<p>The tool must "wake up" the BROM. There are two primary methods:</p>
<p><strong>Legacy BSL (0x7E):</strong> The tool sends a burst of <code>0x7E</code> bytes. The BROM responds with <code>~SPRD3W~</code> or similar. Used by older chips.</p>
<pre><code class="language-cpp">// From uflash/src/bsl_protocol.cpp 
bool BslProtocol::handshake(int timeout_ms) { 
    std::cout &lt;&lt; "Sending 0x7E handshake (32-byte burst)...\n";
    std::vector&lt;uint8_t&gt; burst(32, 0x7E); // BSL_FRAME_TAG
    dev_.write(burst.data(), burst.size()); // ... wait for "~SPRD3W~" response ... 
}
</code></pre>
<p><strong>Modern Host Protocol (0xAE):</strong> The tool sends <code>0xAE 0xAE 0xAE 0xAE</code>. The BROM responds with its version string. This is common in Android 10+ chipsets.</p>
<pre><code class="language-cpp">bool BslProtocol::host_handshake(int timeout_ms) { 
    uint8_t cmd_ae[] = { 0xAE, 0xAE, 0xAE, 0xAE }; 
    dev_.write(cmd_ae, 4); // ... device responds with internal version string ... 
}
</code></pre>
<h3>Boot Service Layer (BSL) Protocol</h3>
<p>Once the handshake is complete, we use the <strong>BSL Protocol</strong> for all further commands. Every command is "framed" with <code>0x7E</code> tags.</p>
<p>Every packet is framed to ensure integrity over noisy serial/USB lines: <code>[7E] [Type: 2B] [Len: 2B] [Payload: N Bytes] [Checksum/CRC: 2B] [7E]</code></p>
<ul>
<li><p><strong>Endianness:</strong> Big-Endian for headers, Little-Endian for payload contents.</p>
</li>
<li><p><strong>Escaping:</strong> If <code>0x7E</code> or <code>0x7D</code> appears inside the packet, it is escaped to <code>0x7D [Byte ^ 0x20]</code>.</p>
</li>
</ul>
<h3>Key Enums &amp; Opcodes</h3>
<table>
<thead>
<tr>
<th>Command</th>
<th>Hex</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td><code>BSL_CMD_CONNECT</code></td>
<td><code>0x00</code></td>
<td>Basic handshake</td>
</tr>
<tr>
<td><code>BSL_CMD_START_DATA</code></td>
<td><code>0x01</code></td>
<td>Prepare for transfer (Name, Address, Size)</td>
</tr>
<tr>
<td><code>BSL_CMD_MIDST_DATA</code></td>
<td><code>0x02</code></td>
<td>Steam data chunks</td>
</tr>
<tr>
<td><code>BSL_CMD_END_DATA</code></td>
<td><code>0x03</code></td>
<td>Finalize transfer &amp; Verify Checksum</td>
</tr>
<tr>
<td><code>BSL_CMD_EXEC_DATA</code></td>
<td><code>0x04</code></td>
<td>Execute code at address</td>
</tr>
<tr>
<td><code>BSL_CMD_READ_FLASH</code></td>
<td><code>0x10</code></td>
<td>Read raw block from flash</td>
</tr>
<tr>
<td><code>BSL_CMD_REPARTITION</code></td>
<td><code>0x0B</code></td>
<td>Format and rebuild eMMC GPT</td>
</tr>
</tbody></table>
<h3>Response Codes</h3>
<ul>
<li><p><code>BSL_REP_ACK (0x80)</code>: Success.</p>
</li>
<li><p><code>BSL_REP_VER (0x81)</code>: Version response.</p>
</li>
<li><p><code>BSL_REP_OPERATION_FAILED (0x84)</code>: Internal device error.</p>
</li>
<li><p><code>BSL_REP_INVALID_PARTITION (0xFE)</code>: Partition name/type mismatch.</p>
</li>
</ul>
<h3><strong>Stage 2: FDL1 (Stage 1 Loader)</strong></h3>
<p>The BROM is extremely limited—it can only read data into a tiny area of SRAM.</p>
<p>FDL1 is small (~40KB) and resides in internal SRAM. Its primary job is to <strong>initialize External DDR RAM</strong>.</p>
<ol>
<li><p>The tool sends <code>BSL_CMD_START_DATA</code> with the address (usually <code>0x5000</code> or <code>0x4000</code>) and size of <code>fdl1-sign.bin</code>.</p>
</li>
<li><p>Data is streamed in chunks via <code>BSL_CMD_MIDST_DATA</code>. <code>BSL_CMD_EXEC_DATA</code> tells the CPU to jump to the FDL1 address.</p>
</li>
</ol>
<p>After FDL1 executes, the device <strong>re-enumerates</strong> as a different USB device. The host must re-find the handle.</p>
<pre><code class="language-cpp">// Flow in main.cpp
bsl.start_data(0x5000, fdl1_size, fdl1_checksum); // Target SRAM address
bsl.midst_data(fdl1_buffer, chunk_size);
bsl.exec_data(0x5000); // Trigger Jump to 0x5000
</code></pre>
<h3>Stage 2: FDL2 (DDR Loader)</h3>
<p>FDL2 is the full "Flash Kernel". We load <code>fdl2-sign.bin</code> into DDR (usually high addresses like <code>0x80000000</code>). FDL2 contains the <strong>Full BSL implementation</strong>, including:</p>
<ul>
<li><p>eMMC/UFS Drivers.</p>
</li>
<li><p>File System support (EXT4/Sparse).</p>
</li>
<li><p>Modern Repartitioning logic.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Across SoCs and Stacks: A Few Months of Platform Engineering]]></title><description><![CDATA[It's Been a Busy Few Months
Over the past few months, I have had the opportunity to work across some really diverse hardware platforms — and it has been one of the most technically enriching stretches]]></description><link>https://blog.ersa.dev/across-socs-and-stacks-a-few-months-of-platform-engineering</link><guid isPermaLink="true">https://blog.ersa.dev/across-socs-and-stacks-a-few-months-of-platform-engineering</guid><category><![CDATA[Android]]></category><category><![CDATA[BSP]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Kernel]]></category><category><![CDATA[NXP]]></category><category><![CDATA[qualcomm]]></category><category><![CDATA[MediaTek เผยชิปที่ถูกเปลี่ยนชื่อ]]></category><category><![CDATA[automotive]]></category><category><![CDATA[Automotive Industry]]></category><category><![CDATA[display]]></category><category><![CDATA[aosp]]></category><dc:creator><![CDATA[Gagan M]]></dc:creator><pubDate>Sat, 21 Mar 2026 10:20:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/69660cc183a72e6c71493989/30aa1422-1ad3-4fe1-8211-98ab023609e5.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>It's Been a Busy Few Months</h2>
<p>Over the past few months, I have had the opportunity to work across some really diverse hardware platforms — and it has been one of the most technically enriching stretches of my career. This post is a brain dump of everything I've touched, from ancient Qualcomm silicon to modern open-source handhelds.</p>
<h2>Display Bring-up on Qualcomm MSM89xx</h2>
<p>I worked on getting multiple displays up and running on Qualcomm MSM89xx hardware — both MIPI and MIPI-to-LVDS bridge configurations. The MSM89xx family is a pretty ancient chip by today's standards, but that's exactly what makes it a good playground for sharpening fundamentals.</p>
<p>This meant going all the way down to <strong>LittleKernel (LK)</strong> — Qualcomm's bootloader — to configure the display stack before the kernel even boots, and then wiring it through the Linux kernel device tree to ensure the panel came alive seamlessly across the handoff from bootloader to kernel.</p>
<p>Specific wins:</p>
<ul>
<li><p>Got a BOE display running on QM215</p>
</li>
<li><p>Got a proof-of-concept MSM8953 board driving an LVDS panel via an auxiliary board using a MIPI-to-LVDS bridge</p>
</li>
</ul>
<h2>IVI Bring-up at Euler</h2>
<p>Worked on the end-to-end device bring-up and maintenance of a new SKU of the IVI platform we ship at Euler. A lot of moving parts across the stack — device tree, kernel, HAL, and everything in between.</p>
<h2>Diving Into the mm-camera Pipeline on QM215</h2>
<p>This one was humbling in the best way. I was trying to get a <strong>TP2815 analog camera solution</strong> up and running on the Qualcomm QM215 platform — and I didn't succeed. Yet.</p>
<p>But the process taught me a ton about how the <strong>mm-camera pipeline</strong> actually works — how the sensor initializes, how the ISP gets configured, and how the camera HAL takes over from the kernel driver. Sometimes the most educational projects are the ones that don't finish on time.</p>
<h2>Toolchain &amp; BSP Modernization</h2>
<p>A few things that fall under the "unglamorous but important" category:</p>
<ul>
<li><p><strong>Ubuntu 14.04 → 24.04 LTS migration</strong> — Several older BSPs had Ubuntu 14.04 as a hard requirement. Got them running cleanly on 24.04 LTS, eliminating the need for a containerized build environment entirely.</p>
</li>
<li><p><strong>Clang for kernel compilation</strong> — Backported patches to enable Clang as the kernel compiler. A modern, maintainable toolchain saves everyone time and reduces the custom environment overhead that slows teams down.</p>
</li>
</ul>
<h2>MediaTek BSP Sleuthing</h2>
<p>Did some cleanup and investigation work on a MediaTek BSP targeting Android 14/15. Relatively minor, but every BSP has its quirks and this was no exception.</p>
<h2>Mecha Comet: Open-Source Handheld Adventures</h2>
<p>This is the section closest to my heart, even if life got in the way of giving it the time it deserved.</p>
<p>I've been working on the <strong>Mecha Systems Comet</strong> as a personal/community project:</p>
<ul>
<li><p>Got <strong>postmarketOS booting</strong> on the device</p>
</li>
<li><p>Isolated and prepared patches for the Comet that fed into the development of <strong>upstream Mecha U-Boot</strong></p>
</li>
<li><p>Enabled <strong>EFI</strong> and set up a proper boot chain using <strong>systemd-boot</strong></p>
</li>
<li><p>Did some reading on <strong>Arm SystemReady</strong> requirements and what it would mean to make the Comet properly compliant</p>
</li>
</ul>
<p>Due to a lot of personal stuff, I wasn't able to get back to it as much as I wanted. But I'm still ideating — and I want to do something a little crazy with it. Hardware too. I just need to learn PCB design first. 😄</p>
<p>A big thank you to <strong>Shoaib Merchant</strong> for the trust, time, and patience in letting me be one of the very first pilot users. ❤️</p>
<h2>Power Management R&amp;D: Android Learnings → Linux Handhelds</h2>
<p>One of the more experimental threads I've been pulling on: exploring what a tool like <code>tuned</code> could look like for <strong>Linux handhelds</strong>, drawing from my experience with <strong>Android's power HAL</strong>.</p>
<p>Android has a fairly mature story around power-aware scheduling, CPU frequency governance, and workload-based tuning. The Linux desktop/handheld space is catching up, but there's a gap. I'm curious whether the patterns from Android's power HAL can translate into something meaningful for devices like the Comet.</p>
<p>Still early R&amp;D — but it's the kind of problem I find genuinely exciting.</p>
<h2>NXP i.MX8 and Android 16</h2>
<p>Dipped into the <strong>NXP i.MX8 Android BSP</strong> for Android 16. I'm also still chipping away at a proper Android port for the Mecha Comet in my free time — the i.MX8 BSP work is feeding directly into that.</p>
<h2>Unisoc PoC</h2>
<p>Also currently working on a <strong>Unisoc proof-of-concept project</strong>. More on that when there's more to share. 😄</p>
<h2>Closing Thought</h2>
<p>Every new platform is a new puzzle — a new schematic to read, a new device tree to write, a new bootloader to spelunk through. And honestly, I wouldn't have it any other way.</p>
<hr />
<p><em>Tags: Android, AOSP, Embedded Systems, BSP, Qualcomm, NXP, Unisoc, MediaTek, LittleKernel, Display Bringup, postmarketOS, IVI, Automotive Embedded, Linux, Power Management, Camera</em></p>
]]></content:encoded></item><item><title><![CDATA[First post!]]></title><description><![CDATA[Hey.
I'm Gagan, and this is my first post on my blog.
I'm not sure what to put here since I'm not that great of a writer - I'm a technical-focused engineer learning new things day by day. Sometimes I ]]></description><link>https://blog.ersa.dev/first-post</link><guid isPermaLink="true">https://blog.ersa.dev/first-post</guid><dc:creator><![CDATA[Gagan M]]></dc:creator><pubDate>Fri, 27 Feb 2026 07:27:44 GMT</pubDate><content:encoded><![CDATA[<p>Hey.</p>
<p>I'm Gagan, and this is my first post on my blog.</p>
<p>I'm not sure what to put here since I'm not that great of a writer - I'm a technical-focused engineer learning new things day by day. Sometimes I forget I'm 22 and expect myself to reach heights that only super experienced folks are at. Guess I'll find a lot of people who share that same feeling.</p>
<p>I've been doing Android as a pastime for over 5 years now (gosh, it's been that long?) and it's been a fun ride... but I feel like custom ROMs and the rest will only push you so far. And BSPs are scary. They're interesting, complex and fun - but considering documentation irrespective is quite scarce, I'm pulling my hair one day or the other. I'd be better at working on them, though. Not pulling my hair out. Don't worry.</p>
<p>Security seems a really interesting field to me - and I try my best to learn what I could do to enforce mandatory access control and process isolation and yada-yada. I want to get better at it - maybe even make my own alternative to QNX, and I'll call it sasta QNX based on Linux RT.</p>
<p>I'm looking for better opportunities in the field of AOSP and embedded Linux - feel free to contact me at <a href="mailto:gagan@ersa.dev">gagan@ersa.dev</a>.</p>
]]></content:encoded></item></channel></rss>