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/d513f02d3937
branches: trunk
changeset: 1004602:d513f02d3937
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 3aba506c6093 -r d513f02d3937 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, ®, 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, ®, 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, ®, 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, ®, 1, data, 1, I2C_F_POLL);
+ return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr, ®, 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