Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/i2c Speed up mode setting a bit and turn off the dis...



details:   https://anonhg.NetBSD.org/src/rev/823e70a1ddbe
branches:  trunk
changeset: 460797:823e70a1ddbe
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Nov 04 10:02:39 2019 +0000

description:
Speed up mode setting a bit and turn off the display while changing modes

diffstat:

 sys/dev/i2c/tda19988.c |  92 +++++++++++++++++++++++++++----------------------
 1 files changed, 51 insertions(+), 41 deletions(-)

diffs (240 lines):

diff -r daa899c3121c -r 823e70a1ddbe sys/dev/i2c/tda19988.c
--- a/sys/dev/i2c/tda19988.c    Mon Nov 04 09:38:38 2019 +0000
+++ b/sys/dev/i2c/tda19988.c    Mon Nov 04 10:02:39 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tda19988.c,v 1.2 2019/11/03 23:28:59 jmcneill Exp $ */
+/* $NetBSD: tda19988.c,v 1.3 2019/11/04 10:02:39 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo%freebsd.org@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tda19988.c,v 1.2 2019/11/03 23:28:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tda19988.c,v 1.3 2019/11/04 10:02:39 jmcneill Exp $");
 
 /*
 * NXP TDA19988 HDMI encoder 
@@ -257,6 +257,7 @@
 
 struct tda19988_softc {
        device_t                sc_dev;
+       int                     sc_phandle;
        i2c_tag_t               sc_i2c;
        i2c_addr_t              sc_addr;
        uint32_t                sc_cec_addr;
@@ -264,12 +265,14 @@
        int                     sc_current_page;
        uint8_t                 *sc_edid;
        uint32_t                sc_edid_len;
+       bool                    sc_edid_valid;
 
        struct drm_bridge       sc_bridge;
        struct tda19988_connector sc_connector;
 
        struct fdt_device_ports sc_ports;
-       struct drm_display_mode sc_curmode;
+
+       enum drm_connector_status sc_last_status;
 };
 
 #define        to_tda_connector(x)     container_of(x, struct tda19988_connector, base)
@@ -280,7 +283,8 @@
        uint8_t buf[2] = { TDA_CURPAGE_ADDR, page };
        int result;
 
-       result = iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, buf, 2, NULL, 0, I2C_F_POLL);
+       result = iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, buf, 2, NULL, 0,
+           cold ? I2C_F_POLL : 0);
        if (result == 0)
                sc->sc_current_page = page;
 
@@ -290,7 +294,8 @@
 static int
 tda19988_cec_read(struct tda19988_softc *sc, uint8_t addr, uint8_t *data)
 {
-       return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_cec_addr, &addr, 1, data, 1, I2C_F_POLL);
+       return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_cec_addr, &addr, 1, data, 1,
+           cold ? I2C_F_POLL : 0);
 }
 
 static int 
@@ -298,7 +303,8 @@
 {
        uint8_t buf[2] = { addr, data };
 
-       return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_cec_addr, buf, 2, NULL, 0, I2C_F_POLL);
+       return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_cec_addr, buf, 2, NULL, 0,
+           cold ? I2C_F_POLL : 0);
 }
 
 static int
@@ -311,19 +317,8 @@
        if (sc->sc_current_page != REGPAGE(addr))
                tda19988_set_page(sc, REGPAGE(addr));
 
-#if notyet
-       return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, &reg, 1, data, len, I2C_F_POLL);
-#else
-       int error, i;
-       for (i = 0; i < len; i++) {
-               error = iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, &reg, 1, &data[i], 1, I2C_F_POLL);
-               if (error != 0)
-                       return error;
-               reg++;
-       }
-
-       return 0;
-#endif
+       return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, &reg, 1, data, len,
+           cold ? I2C_F_POLL : 0);
 }
 
 static int
@@ -336,7 +331,8 @@
        if (sc->sc_current_page != REGPAGE(addr))
                tda19988_set_page(sc, REGPAGE(addr));
 
-       return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, &reg, 1, data, 1, I2C_F_POLL);
+       return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, &reg, 1, data, 1,
+           cold ? I2C_F_POLL : 0);
 }
 
 static int
@@ -347,7 +343,8 @@
        if (sc->sc_current_page != REGPAGE(addr))
                tda19988_set_page(sc, REGPAGE(addr));
 
-       return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, buf, 2, NULL, 0, I2C_F_POLL);
+       return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, buf, 2, NULL, 0,
+           cold ? I2C_F_POLL : 0);
 }
 
 static int
@@ -362,7 +359,8 @@
        if (sc->sc_current_page != REGPAGE(address))
                tda19988_set_page(sc, REGPAGE(address));
 
-       return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, buf, 3, NULL, 0, I2C_F_POLL);
+       return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, buf, 3, NULL, 0,
+           cold ? I2C_F_POLL : 0);
 }
 
 static void
@@ -686,13 +684,6 @@
        tda19988_cec_write(sc, TDA_CEC_FRO_IM_CLK_CTRL,
             CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL);
 
-#if 0
-       if (tda19988_read_edid(sc) < 0) {
-               device_printf(dev, "failed to read EDID\n");
-               return;
-       }
-#endif
-
        /* Default values for RGB 4:4:4 mapping */
        tda19988_reg_write(sc, TDA_VIP_CNTRL_0, 0x23);
        tda19988_reg_write(sc, TDA_VIP_CNTRL_1, 0x01);
@@ -704,15 +695,25 @@
 {
        struct tda19988_connector *tda_connector = to_tda_connector(connector);
        struct tda19988_softc * const sc = tda_connector->sc;
+       enum drm_connector_status status;
        uint8_t data = 0;
 
-       iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
+       iic_acquire_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
        tda19988_cec_read(sc, TDA_CEC_RXSHPDLEV, &data);
-       iic_release_bus(sc->sc_i2c, I2C_F_POLL);
+       iic_release_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
 
-       return (data & RXSHPDLEV_HPD) ?
+       status = (data & RXSHPDLEV_HPD) ?
            connector_status_connected :
            connector_status_disconnected;
+
+       /* On connect, invalidate the last EDID */
+       if (status == connector_status_connected &&
+           sc->sc_last_status != connector_status_connected)
+               sc->sc_edid_valid = false;
+
+       sc->sc_last_status = status;
+
+       return status;
 }
 
 static void
@@ -737,10 +738,15 @@
        struct edid *pedid = NULL;
        int error;
 
-       iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
-       if (tda19988_read_edid(sc) == 0)
+       if (sc->sc_edid_valid) {
                pedid = (struct edid *)sc->sc_edid;
-       iic_release_bus(sc->sc_i2c, I2C_F_POLL);
+       } else {
+               iic_acquire_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
+               if (tda19988_read_edid(sc) == 0)
+                       pedid = (struct edid *)sc->sc_edid;
+               iic_release_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
+               sc->sc_edid_valid = true;
+       }
 
        drm_mode_connector_update_edid_property(connector, pedid);
        if (pedid == NULL)
@@ -805,9 +811,7 @@
 {
        struct tda19988_softc * const sc = bridge->driver_private;
 
-       iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
-       tda19988_init_encoder(sc, &sc->sc_curmode);
-       iic_release_bus(sc->sc_i2c, I2C_F_POLL);
+       fdtbus_pinctrl_set_config(sc->sc_phandle, "default");
 }
 
 static void
@@ -818,6 +822,9 @@
 static void
 tda19988_bridge_disable(struct drm_bridge *bridge)
 {
+       struct tda19988_softc * const sc = bridge->driver_private;
+
+       fdtbus_pinctrl_set_config(sc->sc_phandle, "off");
 }
 
 static void
@@ -831,7 +838,9 @@
 {
        struct tda19988_softc * const sc = bridge->driver_private;
 
-       sc->sc_curmode = *adjusted_mode;
+       iic_acquire_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
+       tda19988_init_encoder(sc, adjusted_mode);
+       iic_release_bus(sc->sc_i2c, cold ? I2C_F_POLL : 0);
 }
 
 static bool
@@ -905,18 +914,19 @@
        const int phandle = ia->ia_cookie;
 
        sc->sc_dev = self;
+       sc->sc_phandle = phandle;
        sc->sc_i2c = ia->ia_tag;
        sc->sc_addr = ia->ia_addr;
        sc->sc_cec_addr = 0x34; /* hardcoded */
        sc->sc_current_page = 0xff;
        sc->sc_edid = kmem_zalloc(EDID_LENGTH, KM_SLEEP);
        sc->sc_edid_len = EDID_LENGTH;
+       sc->sc_edid_valid = false;
+       sc->sc_last_status = connector_status_unknown;
 
        aprint_naive("\n");
        aprint_normal(": NXP TDA19988 HDMI transmitter\n");
 
-       fdtbus_pinctrl_set_config(phandle, "default");
-
        iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
        tda19988_start(sc);
        iic_release_bus(sc->sc_i2c, I2C_F_POLL);



Home | Main Index | Thread Index | Old Index