71GA
71GA

Reputation: 1399

Enabling ann LCD on beaglebone black

I am completely new to the devicetree.

I am trying to connect my LCD panel (datasheet) to the Beaglebone Black's (BBB) expansion connector P8/P9 (BBB referencce manual, p. 70 & 72) and make it work.

I first made sure HDMI is not detected on the I2C. I used this patch:

diff --git a/arch/arm/boot/dts/am335x-boneblack-common.dtsi b/arch/arm/boot/dts/am335x-boneblack-common.dtsi
index 64c3e92..c51e705 100644
--- a/arch/arm/boot/dts/am335x-boneblack-common.dtsi
+++ b/arch/arm/boot/dts/am335x-boneblack-common.dtsi
@@ -79,39 +79,39 @@
     */
    blue-and-red-wiring = "straight";
 
-   port {
-       lcdc_0: endpoint@0 {
-           remote-endpoint = <&hdmi_0>;
-       };
-   };
+   //port {
+   //  lcdc_0: endpoint@0 {
+   //      remote-endpoint = <&hdmi_0>;
+   //  };
+   //};
 };
 
-&i2c0 {
-   tda19988: tda19988@70 {
-       compatible = "nxp,tda998x";
-       reg = <0x70>;
-       nxp,calib-gpios = <&gpio1 25 0>;
-       interrupts-extended = <&gpio1 25 IRQ_TYPE_LEVEL_LOW>;
-
-       pinctrl-names = "default", "off";
-       pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
-       pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
-
-       /* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
-       /* video-ports = <0x234501>; */
-
-       #sound-dai-cells = <0>;
-       audio-ports = < TDA998x_I2S 0x03>;
-
-       ports {
-           port@0 {
-               hdmi_0: endpoint@0 {
-                   remote-endpoint = <&lcdc_0>;
-               };
-           };
-       };
-   };
-};
+//&i2c0 {
+// tda19988: tda19988@70 {
+//     compatible = "nxp,tda998x";
+//     reg = <0x70>;
+//     nxp,calib-gpios = <&gpio1 25 0>;
+//     interrupts-extended = <&gpio1 25 IRQ_TYPE_LEVEL_LOW>;
+//
+//     pinctrl-names = "default", "off";
+//     pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+//     pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+//
+//     /* Convert 24bit BGR to RGB, e.g. cross red and blue wiring */
+//     /* video-ports = <0x234501>; */
+//
+//     #sound-dai-cells = <0>;
+//     audio-ports = < TDA998x_I2S 0x03>;
+//
+//     ports {
+//         port@0 {
+//             hdmi_0: endpoint@0 {
+//                 remote-endpoint = <&lcdc_0>;
+//             };
+//         };
+//     };
+// };
+//};
 
 &rtc {
    system-power-controller;
@@ -162,8 +162,8 @@
            clocks = <&clk_mcasp0>;
        };
 
-       simple-audio-card,codec {
-           sound-dai = <&tda19988>;
-       };
+       //simple-audio-card,codec {
+       //  sound-dai = <&tda19988>;
+       //};
    };
 };

Then I created an overlay &am33xx_pinmux for proper pin muxing as can be seen from the code below. I was referencing AM335x's reference manual & datasheet to do this.

I also read official Linux devicetree "bindings" as indicated in the code's comments and I defined my LCD panel device node panel. I also used node port to connect it to the frame buffer device node fb.

/dts-v1/;

#include "am335x-boneblack.dts"

////////////////////////////////////////////////////////////////////////////////////////////////////
// A:  Change basic info.
// B:  Define a panel following [1], [2], [3].
// C:  Define a frame buffer following [4].
// [1] display/tilcdc/panel.txt
// [2] display/panel/display-timing.txt
// [3] http://www.mctronic.net/products/doc/data_image/scf_tft+sctp/SCF0500133GGU19.pdf
// [4] display/tilcdc/tilcdc.txt
////////////////////////////////////////////////////////////////////////////////////////////////////
/ {
    // A:
    model = "Beaglebone ePCB with LCD";
    compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";

    // B:
    panel {

        compatible = "ti,tilcdc,panel";
        
        panel-info {
            ac-bias = <255>;
            ac-bias-intrpt = <0>;
            dma-burst-sz = <16>;
            bpp = <32>;
            fdd = <128>;
            sync-edge = <0>;
            sync-ctrl = <1>;
            raster-order = <0>;
            fifo-th = <0>;
        };

        display-timings {
            800x480 {
                hactive = <800>;
                vactive = <480>;
                hback-porch = <40>;
                hfront-porch = <40>;
                hsync-len = <48>;
                vback-porch = <29>;
                vfront-porch = <13>;
                vsync-len = <3>;
                clock-frequency = <17000000>;
                hsync-active = <0>;
                vsync-active = <0>;
            };
        };

        port {
            panel_port: endpoint@0 {
                remote-endpoint = <&fb_port>;
            };
        };

    };

    // C:
    fb {
        compatible = "ti,am33xx-tilcdc";
        reg = <0x4830e000 0x1000>;
        interrupt-parent = <&intc>;
        interrupts = <36>;

        port {
            fb_port: endpoint@0 {
                remote-endpoint = <&panel_port>;
            };
        };

    };

};

////////////////////////////////////////////////////////////////////////////////////////////////////
// A: We set pin multiplexing for pins on the Beaglebone blac expansion connector P8
// B: We set pin multiplexing for pins on the Beaglebone blac expansion connector P9
////////////////////////////////////////////////////////////////////////////////////////////////////
&am33xx_pinmux {
    
    // A:
    expansion_connector_p8_pinss: expansion_connector_p8_pins {
        pinctrl-single,pins = <
            0x94 0x17   /* 08  PIN: gpmc_oen_ren --> FUNC: gpio2_3, pullup(✔), out, fast */
            0x7c 0x17   /* 26  PIN: gpmc_csn0 --> FUNC: gpio1_29, pullup(✔), out, fast  */
            0xa0 0x08   /* 45 - lcd_data0 --> FUNC: lcd_data0, pulldown(✘), out, fast */
            0xa4 0x08   /* 46 - lcd_data1 --> FUNC: lcd_data1, pulldown(✘), out, fast */
            0xa8 0x08   /* 43 - lcd_data2 --> FUNC: lcd_data2, pulldown(✘), out, fast */
            0xac 0x08   /* 44 - lcd_data3 --> FUNC: lcd_data3, pulldown(✘), out, fast */
            0xb0 0x08   /* 41 - lcd_data4 --> FUNC: lcd_data4, pulldown(✘), out, fast */
            0xb4 0x08   /* 42 - lcd_data5 --> FUNC: lcd_data5, pulldown(✘), out, fast */
            0xb8 0x08   /* 39 - lcd_data6 --> FUNC: lcd_data6, pulldown(✘), out, fast */
            0xbc 0x08   /* 40 - lcd_data7 --> FUNC: lcd_data7, pulldown(✘), out, fast */
            0xc0 0x08   /* 37 - lcd_data8 --> FUNC: lcd_data8, pulldown(✘), out, fast */
            0xc4 0x08   /* 38 - lcd_data9 --> FUNC: lcd_data9, pulldown(✘), out, fast */
            0xc8 0x08   /* 36 - lcd_data10 --> FUNC: lcd_data10, pulldown(✘), out, fast */
            0xcc 0x08   /* 34 - lcd_data11 --> FUNC: lcd_data11, pulldown(✘), out, fast */
            0xd0 0x08   /* 35 - lcd_data12 --> FUNC: lcd_data12, pulldown(✘), out, fast */
            0xd4 0x08   /* 33 - lcd_data13 --> FUNC: lcd_data13, pulldown(✘), out, fast */
            0xd8 0x08   /* 31 - lcd_data14 --> FUNC: lcd_data14, pulldown(✘), out, fast */
            0xdc 0x08   /* 32 - lcd_data15 --> FUNC: lcd_data15, pulldown(✘), out, fast */
            0x3c 0x09   /* 15 - gpmc_ad15 --> FUNC: lcd_data16, pulldown(✘), out, fast */
            0x38 0x09   /* 16 - gpmc_ad14 --> FUNC: lcd_data17, pulldown(✘), out, fast */
            0x34 0x09   /* 11 - gpmc_ad13 --> FUNC: lcd_data18, pulldown(✘), out, fast */
            0x30 0x09   /* 12 - gpmc_ad12 --> FUNC: lcd_data19, pulldown(✘), out, fast */
            0x2c 0x09   /* 17 - gpmc_ad11 --> FUNC: lcd_data20, pulldown(✘), out, fast */
            0x28 0x09   /* 14 - gpmc_ad10 --> FUNC: lcd_data21, pulldown(✘), out, fast */
            0x24 0x09   /* 13 - gpmc_ad9 --> FUNC: lcd_data22, pulldown(✘), out, fast */
            0x20 0x09   /* 19 - gpmc_ad8 --> FUNC: lcd_data23, pulldown(✘), out, fast */
            0xe0 0x00   /* 27 - lcd_vsync --> FUNC: lcd_vsync, pulldown(✔), out, fast */
            0xe4 0x00   /* 29 - lcd_hsync --> FUNC: lcd_hsync, pulldown(✔), out, fast */
            0xe8 0x00   /* 28 - lcd_pclk --> FUNC: lcd_pclk, pulldown(✔), out, fast */
            0xec 0x00   /* 30 - lcd_ac_bias_en --> FUNC: lcd_ac_bias_en, pulldown(✔), out, fast */
        >;
    };

    // B:
    expansion_connector_p9_pinss: expansion_connector_p9_pins {
        pinctrl-single,pins = <
            0x78  0x17  /* 12 - gpmc_ben1 --> FUNC: gpio1_28, pullup(✔), out, fast */
            0x48  0x0e  /* 14 - gpmc_a2 --> FUNC: ehrpwm1a, pulldown(✘), out, fast */
            0x15c 0x1a  /* 17 - spi0_cs0 --> FUNC: i2c1_scl, pullup(✘), out, fast */
            0x158 0x1a  /* 18 - spi0_d1 --> FUNC: i2c1_sda, pullup(✘), out, fast */
            0x17c 0x1a  /* 19 - uart1_rtsn --> FUNC: i2c2_scl, pullup(✘), out, fast */
            0x178 0x1a  /* 20 - uart1_ctsn --> FUNC: i2c2_sda, pullup(✘), out, fast */
            0x154 0x19  /* 21 - spi0_d0 --> FUNC: uart2_txd, pullup(✘), out, fast */
            0x150 0x19  /* 22 - spi0_sclk --> FUNC: uart2_rxd, pullup(✘), out, fast */
            0x184 0x18  /* 24 - uart1_txd --> FUNC: uart1_txd, pullup(✘), out, fast */
            0x180 0x18  /* 26 - uart1_rxd --> FUNC: uart1_rxd, pullup(✘), out, fast */
            0x1ac 0x17  /* 25 - mcasp0_ahclkx --> FUNC: gpio3_21, pullup(✔), out, fast */
            0x1a4 0x17  /* 27 - mcasp0_fsr --> FUNC: gpio3_19, pullup(✔), out, fast */
            0x164 0x17  /* 42 - eCAP0_in_PWM0_out --> FUNC: gpio0_7, pullup(✔), out, fast */
        >;
    };
};

Here is the electronic schematics for BBB's expansion connector P8/P9 where I've written functions assigned to each pin:

enter image description here

Here is the electronic schematics for the display whose signals lines are connected to P8 & P9.

enter image description here

After I built the Linux image and used it to boot the device I noticed that frame buffer device /dev/fb0 was created, but display shows nothing! It is white and is flickering a bit.

Any suggestions on how to debug this?

Upvotes: 2

Views: 965

Answers (1)

De Funct
De Funct

Reputation: 495

/dev/pwm/ should show you some PWM peripherals. If this is not the case, you can always add the proper .dtbo in the /boot/uEnv.txt file. BONE-BUSES is a thing or at least was during the GSoC of 2021.

Nevertheless, here: https://github.com/beagleboard/BeagleBoard-DeviceTrees/blob/v4.19.x-ti-overlays/src/arm/overlays/BONE-PWM1.dts is one way to handle specified PWM peripherals. IN that /src/arm/overlays/ directory, there are many PWM peripherals one can use.

In the BeagleBoard-DeviceTrees repo, after cloning with git, use these commands once in the above directory:

If you are using v4.19.x-ti-overlays with one of their images with a kernel of 4.19.x, then:

  1. git checkout v4.19x-ti-overlays
  2. switch up your GPIO and PWM .dts files or just use their .dts files
  3. then, in the BeagleBoard-DeviceTrees directory, type make
  4. then, sudo make install

After they are built and available, you can simply add them in the /boot/uEnv.txt file as u-boot_overlays in the .dtbo format.

This should get you a bit further than not being able to handle PWM and GPIO.


/*
 * Copyright (C) 2020 Deepak Khatri <[email protected]>
 * See Cape Interface Spec page for more info on Bone Buses
 * https://elinux.org/Beagleboard:BeagleBone_cape_interface_spec
 *
 * P9.14 Backlight overlay for BBBWL/BBB/BBAI
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
 
/dts-v1/;
/plugin/;

/*
* Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
*/
&{/chosen} {
    overlays {
        BONE-BACKLIGHT = __TIMESTAMP__;
    };
};

/*
 * Update the default pinmux of the pins.
 * See these files for the phandles (&P9_* & &P8_*)
 * BeagleBoard-DeviceTrees/v4.19.x-ti-overlays/src/arm/am335x-bone-common-univ.dtsi
 * BeagleBoard-DeviceTrees/v4.19.x-ti-overlays/src/arm/am572x-bone-common-univ.dtsi
 */
&ocp {
    P9_14_pinmux { pinctrl-0 = <&P9_14_pwm_pin>; };    /* BACKLIGHT */

};

/*
 * See these files for the phandles (&bone_*) and other bone bus nodes
 * BeagleBoard-DeviceTrees/v4.19.x-ti-overlays/src/arm/bbai-bone-buses.dtsi
 * BeagleBoard-DeviceTrees/v4.19.x-ti-overlays/src/arm/bbb-bone-buses.dtsi
 */
&bone_pwm_1 {
    status = "okay";
};

&{/} {
    backlight {
        status = "okay";
        compatible = "pwm-backlight";
        pwms = <&bone_pwm_1 0 500000 0>;
        brightness-levels = <
            0  1  2  3  4  5  6  7  8  9
            10 11 12 13 14 15 16 17 18 19
            20 21 22 23 24 25 26 27 28 29
            30 31 32 33 34 35 36 37 38 39
            40 41 42 43 44 45 46 47 48 49
            50 51 52 53 54 55 56 57 58 59
            60 61 62 63 64 65 66 67 68 69
            70 71 72 73 74 75 76 77 78 79
            80 81 82 83 84 85 86 87 88 89
            90 91 92 93 94 95 96 97 98 99
            100
        >;
        default-brightness-level = <100>;
    };
};

That is for backlighting from PWM on the BBB which can be found here: https://github.com/beagleboard/BeagleBoard-DeviceTrees/blob/v4.19.x-ti-overlays/src/arm/overlays/BONE-BACKLIGHT.dts

and...

Another good example of this promoting your LCD Cape for the BBB is located here: https://github.com/beagleboard/bb.org-overlays/blob/master/src/arm/BB-BONE-4D4C-01-00A1.dts . You can actually see where and how different selections and includes are made.

Upvotes: 1

Related Questions