diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_gmbus.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_gmbus.c | 576 |
1 files changed, 322 insertions, 254 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c index fcf47f98ea36..795012d7c24c 100644 --- a/drivers/gpu/drm/i915/display/intel_gmbus.c +++ b/drivers/gpu/drm/i915/display/intel_gmbus.c @@ -30,17 +30,52 @@ #include <linux/export.h> #include <linux/i2c-algo-bit.h> #include <linux/i2c.h> +#include <linux/iopoll.h> -#include <drm/drm_hdcp.h> +#include <drm/drm_print.h> +#include <drm/display/drm_hdcp_helper.h> #include "i915_drv.h" +#include "i915_irq.h" +#include "i915_reg.h" #include "intel_de.h" +#include "intel_display_regs.h" #include "intel_display_types.h" +#include "intel_display_wa.h" #include "intel_gmbus.h" +#include "intel_gmbus_regs.h" + +struct intel_gmbus { + struct i2c_adapter adapter; +#define GMBUS_FORCE_BIT_RETRY (1U << 31) + u32 force_bit; + u32 reg0; + i915_reg_t gpio_reg; + struct i2c_algo_bit_data bit_algo; + struct intel_display *display; +}; + +enum gmbus_gpio { + GPIOA, + GPIOB, + GPIOC, + GPIOD, + GPIOE, + GPIOF, + GPIOG, + GPIOH, + __GPIOI_UNUSED, + GPIOJ, + GPIOK, + GPIOL, + GPIOM, + GPION, + GPIOO, +}; struct gmbus_pin { const char *name; - enum i915_gpio gpio; + enum gmbus_gpio gpio; }; /* Map gmbus pin pairs to names and registers. */ @@ -98,47 +133,70 @@ static const struct gmbus_pin gmbus_pins_dg1[] = { [GMBUS_PIN_4_CNP] = { "dpd", GPIOE }, }; -/* pin is expected to be valid */ -static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *dev_priv, - unsigned int pin) -{ - if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) - return &gmbus_pins_dg1[pin]; - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - return &gmbus_pins_icp[pin]; - else if (HAS_PCH_CNP(dev_priv)) - return &gmbus_pins_cnp[pin]; - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - return &gmbus_pins_bxt[pin]; - else if (DISPLAY_VER(dev_priv) == 9) - return &gmbus_pins_skl[pin]; - else if (IS_BROADWELL(dev_priv)) - return &gmbus_pins_bdw[pin]; - else - return &gmbus_pins[pin]; -} +static const struct gmbus_pin gmbus_pins_dg2[] = { + [GMBUS_PIN_1_BXT] = { "dpa", GPIOB }, + [GMBUS_PIN_2_BXT] = { "dpb", GPIOC }, + [GMBUS_PIN_3_BXT] = { "dpc", GPIOD }, + [GMBUS_PIN_4_CNP] = { "dpd", GPIOE }, + [GMBUS_PIN_9_TC1_ICP] = { "tc1", GPIOJ }, +}; -bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv, - unsigned int pin) -{ - unsigned int size; +static const struct gmbus_pin gmbus_pins_mtp[] = { + [GMBUS_PIN_1_BXT] = { "dpa", GPIOB }, + [GMBUS_PIN_2_BXT] = { "dpb", GPIOC }, + [GMBUS_PIN_3_BXT] = { "dpc", GPIOD }, + [GMBUS_PIN_4_CNP] = { "dpd", GPIOE }, + [GMBUS_PIN_5_MTP] = { "dpe", GPIOF }, + [GMBUS_PIN_9_TC1_ICP] = { "tc1", GPIOJ }, + [GMBUS_PIN_10_TC2_ICP] = { "tc2", GPIOK }, + [GMBUS_PIN_11_TC3_ICP] = { "tc3", GPIOL }, + [GMBUS_PIN_12_TC4_ICP] = { "tc4", GPIOM }, +}; - if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) +static const struct gmbus_pin *get_gmbus_pin(struct intel_display *display, + unsigned int pin) +{ + const struct gmbus_pin *pins; + size_t size; + + if (INTEL_PCH_TYPE(display) >= PCH_MTL) { + pins = gmbus_pins_mtp; + size = ARRAY_SIZE(gmbus_pins_mtp); + } else if (INTEL_PCH_TYPE(display) >= PCH_DG2) { + pins = gmbus_pins_dg2; + size = ARRAY_SIZE(gmbus_pins_dg2); + } else if (INTEL_PCH_TYPE(display) >= PCH_DG1) { + pins = gmbus_pins_dg1; size = ARRAY_SIZE(gmbus_pins_dg1); - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) + } else if (INTEL_PCH_TYPE(display) >= PCH_ICP) { + pins = gmbus_pins_icp; size = ARRAY_SIZE(gmbus_pins_icp); - else if (HAS_PCH_CNP(dev_priv)) + } else if (HAS_PCH_CNP(display)) { + pins = gmbus_pins_cnp; size = ARRAY_SIZE(gmbus_pins_cnp); - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + } else if (display->platform.geminilake || display->platform.broxton) { + pins = gmbus_pins_bxt; size = ARRAY_SIZE(gmbus_pins_bxt); - else if (DISPLAY_VER(dev_priv) == 9) + } else if (DISPLAY_VER(display) == 9) { + pins = gmbus_pins_skl; size = ARRAY_SIZE(gmbus_pins_skl); - else if (IS_BROADWELL(dev_priv)) + } else if (display->platform.broadwell) { + pins = gmbus_pins_bdw; size = ARRAY_SIZE(gmbus_pins_bdw); - else + } else { + pins = gmbus_pins; size = ARRAY_SIZE(gmbus_pins); + } + + if (pin >= size || !pins[pin].name) + return NULL; - return pin < size && get_gmbus_pin(dev_priv, pin)->name; + return &pins[pin]; +} + +bool intel_gmbus_is_valid_pin(struct intel_display *display, unsigned int pin) +{ + return get_gmbus_pin(display, pin); } /* Intel GPIO access functions */ @@ -152,101 +210,83 @@ to_intel_gmbus(struct i2c_adapter *i2c) } void -intel_gmbus_reset(struct drm_i915_private *dev_priv) +intel_gmbus_reset(struct intel_display *display) { - intel_de_write(dev_priv, GMBUS0, 0); - intel_de_write(dev_priv, GMBUS4, 0); + intel_de_write(display, GMBUS0(display), 0); + intel_de_write(display, GMBUS4(display), 0); } -static void pnv_gmbus_clock_gating(struct drm_i915_private *dev_priv, +static void pnv_gmbus_clock_gating(struct intel_display *display, bool enable) { - u32 val; - /* When using bit bashing for I2C, this bit needs to be set to 1 */ - val = intel_de_read(dev_priv, DSPCLK_GATE_D); - if (!enable) - val |= PNV_GMBUSUNIT_CLOCK_GATE_DISABLE; - else - val &= ~PNV_GMBUSUNIT_CLOCK_GATE_DISABLE; - intel_de_write(dev_priv, DSPCLK_GATE_D, val); + intel_de_rmw(display, DSPCLK_GATE_D, + PNV_GMBUSUNIT_CLOCK_GATE_DISABLE, + !enable ? PNV_GMBUSUNIT_CLOCK_GATE_DISABLE : 0); } -static void pch_gmbus_clock_gating(struct drm_i915_private *dev_priv, +static void pch_gmbus_clock_gating(struct intel_display *display, bool enable) { - u32 val; - - val = intel_de_read(dev_priv, SOUTH_DSPCLK_GATE_D); - if (!enable) - val |= PCH_GMBUSUNIT_CLOCK_GATE_DISABLE; - else - val &= ~PCH_GMBUSUNIT_CLOCK_GATE_DISABLE; - intel_de_write(dev_priv, SOUTH_DSPCLK_GATE_D, val); + intel_de_rmw(display, SOUTH_DSPCLK_GATE_D, + PCH_GMBUSUNIT_CLOCK_GATE_DISABLE, + !enable ? PCH_GMBUSUNIT_CLOCK_GATE_DISABLE : 0); } -static void bxt_gmbus_clock_gating(struct drm_i915_private *dev_priv, +static void bxt_gmbus_clock_gating(struct intel_display *display, bool enable) { - u32 val; - - val = intel_de_read(dev_priv, GEN9_CLKGATE_DIS_4); - if (!enable) - val |= BXT_GMBUS_GATING_DIS; - else - val &= ~BXT_GMBUS_GATING_DIS; - intel_de_write(dev_priv, GEN9_CLKGATE_DIS_4, val); + intel_de_rmw(display, GEN9_CLKGATE_DIS_4, BXT_GMBUS_GATING_DIS, + !enable ? BXT_GMBUS_GATING_DIS : 0); } static u32 get_reserved(struct intel_gmbus *bus) { - struct drm_i915_private *i915 = bus->dev_priv; - struct intel_uncore *uncore = &i915->uncore; - u32 reserved = 0; + struct intel_display *display = bus->display; + u32 preserve_bits = 0; + + if (display->platform.i830 || display->platform.i845g) + return 0; /* On most chips, these bits must be preserved in software. */ - if (!IS_I830(i915) && !IS_I845G(i915)) - reserved = intel_uncore_read_notrace(uncore, bus->gpio_reg) & - (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); + preserve_bits |= GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE; - return reserved; + /* Wa_16025573575: the masks bits need to be preserved through out */ + if (intel_display_wa(display, 16025573575)) + preserve_bits |= GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_VAL_MASK | + GPIO_DATA_DIR_MASK | GPIO_DATA_VAL_MASK; + + return intel_de_read_notrace(display, bus->gpio_reg) & preserve_bits; } static int get_clock(void *data) { struct intel_gmbus *bus = data; - struct intel_uncore *uncore = &bus->dev_priv->uncore; + struct intel_display *display = bus->display; u32 reserved = get_reserved(bus); - intel_uncore_write_notrace(uncore, - bus->gpio_reg, - reserved | GPIO_CLOCK_DIR_MASK); - intel_uncore_write_notrace(uncore, bus->gpio_reg, reserved); + intel_de_write_notrace(display, bus->gpio_reg, reserved | GPIO_CLOCK_DIR_MASK); + intel_de_write_notrace(display, bus->gpio_reg, reserved); - return (intel_uncore_read_notrace(uncore, bus->gpio_reg) & - GPIO_CLOCK_VAL_IN) != 0; + return (intel_de_read_notrace(display, bus->gpio_reg) & GPIO_CLOCK_VAL_IN) != 0; } static int get_data(void *data) { struct intel_gmbus *bus = data; - struct intel_uncore *uncore = &bus->dev_priv->uncore; + struct intel_display *display = bus->display; u32 reserved = get_reserved(bus); - intel_uncore_write_notrace(uncore, - bus->gpio_reg, - reserved | GPIO_DATA_DIR_MASK); - intel_uncore_write_notrace(uncore, bus->gpio_reg, reserved); + intel_de_write_notrace(display, bus->gpio_reg, reserved | GPIO_DATA_DIR_MASK); + intel_de_write_notrace(display, bus->gpio_reg, reserved); - return (intel_uncore_read_notrace(uncore, bus->gpio_reg) & - GPIO_DATA_VAL_IN) != 0; + return (intel_de_read_notrace(display, bus->gpio_reg) & GPIO_DATA_VAL_IN) != 0; } static void set_clock(void *data, int state_high) { struct intel_gmbus *bus = data; - struct intel_uncore *uncore = &bus->dev_priv->uncore; + struct intel_display *display = bus->display; u32 reserved = get_reserved(bus); u32 clock_bits; @@ -256,16 +296,14 @@ static void set_clock(void *data, int state_high) clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_VAL_MASK; - intel_uncore_write_notrace(uncore, - bus->gpio_reg, - reserved | clock_bits); - intel_uncore_posting_read(uncore, bus->gpio_reg); + intel_de_write_notrace(display, bus->gpio_reg, reserved | clock_bits); + intel_de_posting_read(display, bus->gpio_reg); } static void set_data(void *data, int state_high) { struct intel_gmbus *bus = data; - struct intel_uncore *uncore = &bus->dev_priv->uncore; + struct intel_display *display = bus->display; u32 reserved = get_reserved(bus); u32 data_bits; @@ -275,22 +313,39 @@ static void set_data(void *data, int state_high) data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | GPIO_DATA_VAL_MASK; - intel_uncore_write_notrace(uncore, bus->gpio_reg, reserved | data_bits); - intel_uncore_posting_read(uncore, bus->gpio_reg); + intel_de_write_notrace(display, bus->gpio_reg, reserved | data_bits); + intel_de_posting_read(display, bus->gpio_reg); +} + +static void +ptl_handle_mask_bits(struct intel_gmbus *bus, bool set) +{ + struct intel_display *display = bus->display; + u32 reg_val = intel_de_read_notrace(display, bus->gpio_reg); + u32 mask_bits = GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_VAL_MASK | + GPIO_DATA_DIR_MASK | GPIO_DATA_VAL_MASK; + if (set) + reg_val |= mask_bits; + else + reg_val &= ~mask_bits; + + intel_de_write_notrace(display, bus->gpio_reg, reg_val); + intel_de_posting_read(display, bus->gpio_reg); } static int intel_gpio_pre_xfer(struct i2c_adapter *adapter) { - struct intel_gmbus *bus = container_of(adapter, - struct intel_gmbus, - adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; + struct intel_gmbus *bus = to_intel_gmbus(adapter); + struct intel_display *display = bus->display; - intel_gmbus_reset(dev_priv); + intel_gmbus_reset(display); - if (IS_PINEVIEW(dev_priv)) - pnv_gmbus_clock_gating(dev_priv, false); + if (display->platform.pineview) + pnv_gmbus_clock_gating(display, false); + + if (intel_display_wa(display, 16025573575)) + ptl_handle_mask_bits(bus, true); set_data(bus, 1); set_clock(bus, 1); @@ -301,27 +356,27 @@ intel_gpio_pre_xfer(struct i2c_adapter *adapter) static void intel_gpio_post_xfer(struct i2c_adapter *adapter) { - struct intel_gmbus *bus = container_of(adapter, - struct intel_gmbus, - adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; + struct intel_gmbus *bus = to_intel_gmbus(adapter); + struct intel_display *display = bus->display; set_data(bus, 1); set_clock(bus, 1); - if (IS_PINEVIEW(dev_priv)) - pnv_gmbus_clock_gating(dev_priv, true); + if (display->platform.pineview) + pnv_gmbus_clock_gating(display, true); + + if (intel_display_wa(display, 16025573575)) + ptl_handle_mask_bits(bus, false); } static void -intel_gpio_setup(struct intel_gmbus *bus, unsigned int pin) +intel_gpio_setup(struct intel_gmbus *bus, i915_reg_t gpio_reg) { - struct drm_i915_private *dev_priv = bus->dev_priv; struct i2c_algo_bit_data *algo; algo = &bus->bit_algo; - bus->gpio_reg = GPIO(get_gmbus_pin(dev_priv, pin)->gpio); + bus->gpio_reg = gpio_reg; bus->adapter.algo_data = algo; algo->setsda = set_data; algo->setscl = set_clock; @@ -334,7 +389,17 @@ intel_gpio_setup(struct intel_gmbus *bus, unsigned int pin) algo->data = bus; } -static int gmbus_wait(struct drm_i915_private *dev_priv, u32 status, u32 irq_en) +static bool has_gmbus_irq(struct intel_display *display) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + /* + * encoder->shutdown() may want to use GMBUS + * after irqs have already been disabled. + */ + return HAS_GMBUS_IRQ(display) && intel_irqs_enabled(i915); +} + +static int gmbus_wait(struct intel_display *display, u32 status, u32 irq_en) { DEFINE_WAIT(wait); u32 gmbus2; @@ -344,21 +409,24 @@ static int gmbus_wait(struct drm_i915_private *dev_priv, u32 status, u32 irq_en) * we also need to check for NAKs besides the hw ready/idle signal, we * need to wake up periodically and check that ourselves. */ - if (!HAS_GMBUS_IRQ(dev_priv)) + if (!has_gmbus_irq(display)) irq_en = 0; - add_wait_queue(&dev_priv->gmbus_wait_queue, &wait); - intel_de_write_fw(dev_priv, GMBUS4, irq_en); + add_wait_queue(&display->gmbus.wait_queue, &wait); + intel_de_write_fw(display, GMBUS4(display), irq_en); status |= GMBUS_SATOER; - ret = wait_for_us((gmbus2 = intel_de_read_fw(dev_priv, GMBUS2)) & status, - 2); + + ret = poll_timeout_us_atomic(gmbus2 = intel_de_read_fw(display, GMBUS2(display)), + gmbus2 & status, + 0, 2, false); if (ret) - ret = wait_for((gmbus2 = intel_de_read_fw(dev_priv, GMBUS2)) & status, - 50); + ret = poll_timeout_us(gmbus2 = intel_de_read_fw(display, GMBUS2(display)), + gmbus2 & status, + 500, 50 * 1000, false); - intel_de_write_fw(dev_priv, GMBUS4, 0); - remove_wait_queue(&dev_priv->gmbus_wait_queue, &wait); + intel_de_write_fw(display, GMBUS4(display), 0); + remove_wait_queue(&display->gmbus.wait_queue, &wait); if (gmbus2 & GMBUS_SATOER) return -ENXIO; @@ -367,7 +435,7 @@ static int gmbus_wait(struct drm_i915_private *dev_priv, u32 status, u32 irq_en) } static int -gmbus_wait_idle(struct drm_i915_private *dev_priv) +gmbus_wait_idle(struct intel_display *display) { DEFINE_WAIT(wait); u32 irq_enable; @@ -375,35 +443,33 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv) /* Important: The hw handles only the first bit, so set only one! */ irq_enable = 0; - if (HAS_GMBUS_IRQ(dev_priv)) + if (has_gmbus_irq(display)) irq_enable = GMBUS_IDLE_EN; - add_wait_queue(&dev_priv->gmbus_wait_queue, &wait); - intel_de_write_fw(dev_priv, GMBUS4, irq_enable); + add_wait_queue(&display->gmbus.wait_queue, &wait); + intel_de_write_fw(display, GMBUS4(display), irq_enable); - ret = intel_wait_for_register_fw(&dev_priv->uncore, - GMBUS2, GMBUS_ACTIVE, 0, - 10); + ret = intel_de_wait_fw_ms(display, GMBUS2(display), GMBUS_ACTIVE, 0, 10, NULL); - intel_de_write_fw(dev_priv, GMBUS4, 0); - remove_wait_queue(&dev_priv->gmbus_wait_queue, &wait); + intel_de_write_fw(display, GMBUS4(display), 0); + remove_wait_queue(&display->gmbus.wait_queue, &wait); return ret; } -static unsigned int gmbus_max_xfer_size(struct drm_i915_private *dev_priv) +static unsigned int gmbus_max_xfer_size(struct intel_display *display) { - return DISPLAY_VER(dev_priv) >= 9 ? GEN9_GMBUS_BYTE_COUNT_MAX : + return DISPLAY_VER(display) >= 9 ? GEN9_GMBUS_BYTE_COUNT_MAX : GMBUS_BYTE_COUNT_MAX; } static int -gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv, +gmbus_xfer_read_chunk(struct intel_display *display, unsigned short addr, u8 *buf, unsigned int len, u32 gmbus0_reg, u32 gmbus1_index) { unsigned int size = len; - bool burst_read = len > gmbus_max_xfer_size(dev_priv); + bool burst_read = len > gmbus_max_xfer_size(display); bool extra_byte_added = false; if (burst_read) { @@ -416,21 +482,21 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv, len++; } size = len % 256 + 256; - intel_de_write_fw(dev_priv, GMBUS0, + intel_de_write_fw(display, GMBUS0(display), gmbus0_reg | GMBUS_BYTE_CNT_OVERRIDE); } - intel_de_write_fw(dev_priv, GMBUS1, + intel_de_write_fw(display, GMBUS1(display), gmbus1_index | GMBUS_CYCLE_WAIT | (size << GMBUS_BYTE_COUNT_SHIFT) | (addr << GMBUS_SLAVE_ADDR_SHIFT) | GMBUS_SLAVE_READ | GMBUS_SW_RDY); while (len) { int ret; u32 val, loop = 0; - ret = gmbus_wait(dev_priv, GMBUS_HW_RDY, GMBUS_HW_RDY_EN); + ret = gmbus_wait(display, GMBUS_HW_RDY, GMBUS_HW_RDY_EN); if (ret) return ret; - val = intel_de_read_fw(dev_priv, GMBUS3); + val = intel_de_read_fw(display, GMBUS3(display)); do { if (extra_byte_added && len == 1) break; @@ -441,7 +507,7 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv, if (burst_read && len == size - 4) /* Reset the override bit */ - intel_de_write_fw(dev_priv, GMBUS0, gmbus0_reg); + intel_de_write_fw(display, GMBUS0(display), gmbus0_reg); } return 0; @@ -450,7 +516,7 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv, /* * HW spec says that 512Bytes in Burst read need special treatment. * But it doesn't talk about other multiple of 256Bytes. And couldn't locate - * an I2C slave, which supports such a lengthy burst read too for experiments. + * an I2C target, which supports such a lengthy burst read too for experiments. * * So until things get clarified on HW support, to avoid the burst read length * in fold of 256Bytes except 512, max burst read length is fixed at 767Bytes. @@ -458,7 +524,7 @@ gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv, #define INTEL_GMBUS_BURST_READ_MAX_LEN 767U static int -gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, +gmbus_xfer_read(struct intel_display *display, struct i2c_msg *msg, u32 gmbus0_reg, u32 gmbus1_index) { u8 *buf = msg->buf; @@ -467,12 +533,12 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, int ret; do { - if (HAS_GMBUS_BURST_READ(dev_priv)) + if (HAS_GMBUS_BURST_READ(display)) len = min(rx_size, INTEL_GMBUS_BURST_READ_MAX_LEN); else - len = min(rx_size, gmbus_max_xfer_size(dev_priv)); + len = min(rx_size, gmbus_max_xfer_size(display)); - ret = gmbus_xfer_read_chunk(dev_priv, msg->addr, buf, len, + ret = gmbus_xfer_read_chunk(display, msg->addr, buf, len, gmbus0_reg, gmbus1_index); if (ret) return ret; @@ -485,7 +551,7 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, } static int -gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, +gmbus_xfer_write_chunk(struct intel_display *display, unsigned short addr, u8 *buf, unsigned int len, u32 gmbus1_index) { @@ -498,8 +564,8 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, len -= 1; } - intel_de_write_fw(dev_priv, GMBUS3, val); - intel_de_write_fw(dev_priv, GMBUS1, + intel_de_write_fw(display, GMBUS3(display), val); + intel_de_write_fw(display, GMBUS1(display), gmbus1_index | GMBUS_CYCLE_WAIT | (chunk_size << GMBUS_BYTE_COUNT_SHIFT) | (addr << GMBUS_SLAVE_ADDR_SHIFT) | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); while (len) { int ret; @@ -509,9 +575,9 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, val |= *buf++ << (8 * loop); } while (--len && ++loop < 4); - intel_de_write_fw(dev_priv, GMBUS3, val); + intel_de_write_fw(display, GMBUS3(display), val); - ret = gmbus_wait(dev_priv, GMBUS_HW_RDY, GMBUS_HW_RDY_EN); + ret = gmbus_wait(display, GMBUS_HW_RDY, GMBUS_HW_RDY_EN); if (ret) return ret; } @@ -520,7 +586,7 @@ gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, } static int -gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg, +gmbus_xfer_write(struct intel_display *display, struct i2c_msg *msg, u32 gmbus1_index) { u8 *buf = msg->buf; @@ -529,9 +595,9 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg, int ret; do { - len = min(tx_size, gmbus_max_xfer_size(dev_priv)); + len = min(tx_size, gmbus_max_xfer_size(display)); - ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len, + ret = gmbus_xfer_write_chunk(display, msg->addr, buf, len, gmbus1_index); if (ret) return ret; @@ -558,7 +624,7 @@ gmbus_is_index_xfer(struct i2c_msg *msgs, int i, int num) } static int -gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs, +gmbus_index_xfer(struct intel_display *display, struct i2c_msg *msgs, u32 gmbus0_reg) { u32 gmbus1_index = 0; @@ -574,17 +640,17 @@ gmbus_index_xfer(struct drm_i915_private *dev_priv, struct i2c_msg *msgs, /* GMBUS5 holds 16-bit index */ if (gmbus5) - intel_de_write_fw(dev_priv, GMBUS5, gmbus5); + intel_de_write_fw(display, GMBUS5(display), gmbus5); if (msgs[1].flags & I2C_M_RD) - ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus0_reg, + ret = gmbus_xfer_read(display, &msgs[1], gmbus0_reg, gmbus1_index); else - ret = gmbus_xfer_write(dev_priv, &msgs[1], gmbus1_index); + ret = gmbus_xfer_write(display, &msgs[1], gmbus1_index); /* Clear GMBUS5 after each index transfer */ if (gmbus5) - intel_de_write_fw(dev_priv, GMBUS5, 0); + intel_de_write_fw(display, GMBUS5(display), 0); return ret; } @@ -593,37 +659,35 @@ static int do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num, u32 gmbus0_source) { - struct intel_gmbus *bus = container_of(adapter, - struct intel_gmbus, - adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; + struct intel_gmbus *bus = to_intel_gmbus(adapter); + struct intel_display *display = bus->display; int i = 0, inc, try = 0; int ret = 0; - /* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */ - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - bxt_gmbus_clock_gating(dev_priv, false); - else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv)) - pch_gmbus_clock_gating(dev_priv, false); + /* Display WA #0868: skl,bxt,kbl,cfl,glk */ + if (display->platform.geminilake || display->platform.broxton) + bxt_gmbus_clock_gating(display, false); + else if (HAS_PCH_SPT(display) || HAS_PCH_CNP(display)) + pch_gmbus_clock_gating(display, false); retry: - intel_de_write_fw(dev_priv, GMBUS0, gmbus0_source | bus->reg0); + intel_de_write_fw(display, GMBUS0(display), gmbus0_source | bus->reg0); for (; i < num; i += inc) { inc = 1; if (gmbus_is_index_xfer(msgs, i, num)) { - ret = gmbus_index_xfer(dev_priv, &msgs[i], + ret = gmbus_index_xfer(display, &msgs[i], gmbus0_source | bus->reg0); inc = 2; /* an index transmission is two msgs */ } else if (msgs[i].flags & I2C_M_RD) { - ret = gmbus_xfer_read(dev_priv, &msgs[i], + ret = gmbus_xfer_read(display, &msgs[i], gmbus0_source | bus->reg0, 0); } else { - ret = gmbus_xfer_write(dev_priv, &msgs[i], 0); + ret = gmbus_xfer_write(display, &msgs[i], 0); } if (!ret) - ret = gmbus_wait(dev_priv, + ret = gmbus_wait(display, GMBUS_HW_WAIT_PHASE, GMBUS_HW_WAIT_EN); if (ret == -ETIMEDOUT) goto timeout; @@ -635,19 +699,19 @@ retry: * a STOP on the very first cycle. To simplify the code we * unconditionally generate the STOP condition with an additional gmbus * cycle. */ - intel_de_write_fw(dev_priv, GMBUS1, GMBUS_CYCLE_STOP | GMBUS_SW_RDY); + intel_de_write_fw(display, GMBUS1(display), GMBUS_CYCLE_STOP | GMBUS_SW_RDY); /* Mark the GMBUS interface as disabled after waiting for idle. * We will re-enable it at the start of the next xfer, * till then let it sleep. */ - if (gmbus_wait_idle(dev_priv)) { - drm_dbg_kms(&dev_priv->drm, + if (gmbus_wait_idle(display)) { + drm_dbg_kms(display->drm, "GMBUS [%s] timed out waiting for idle\n", adapter->name); ret = -ETIMEDOUT; } - intel_de_write_fw(dev_priv, GMBUS0, 0); + intel_de_write_fw(display, GMBUS0(display), 0); ret = ret ?: i; goto out; @@ -666,8 +730,8 @@ clear_err: * it's slow responding and only answers on the 2nd retry. */ ret = -ENXIO; - if (gmbus_wait_idle(dev_priv)) { - drm_dbg_kms(&dev_priv->drm, + if (gmbus_wait_idle(display)) { + drm_dbg_kms(display->drm, "GMBUS [%s] timed out after NAK\n", adapter->name); ret = -ETIMEDOUT; @@ -675,13 +739,13 @@ clear_err: /* Toggle the Software Clear Interrupt bit. This has the effect * of resetting the GMBUS controller and so clearing the - * BUS_ERROR raised by the slave's NAK. + * BUS_ERROR raised by the target's NAK. */ - intel_de_write_fw(dev_priv, GMBUS1, GMBUS_SW_CLR_INT); - intel_de_write_fw(dev_priv, GMBUS1, 0); - intel_de_write_fw(dev_priv, GMBUS0, 0); + intel_de_write_fw(display, GMBUS1(display), GMBUS_SW_CLR_INT); + intel_de_write_fw(display, GMBUS1(display), 0); + intel_de_write_fw(display, GMBUS0(display), 0); - drm_dbg_kms(&dev_priv->drm, "GMBUS [%s] NAK for addr: %04x %c(%d)\n", + drm_dbg_kms(display->drm, "GMBUS [%s] NAK for addr: %04x %c(%d)\n", adapter->name, msgs[i].addr, (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); @@ -692,7 +756,7 @@ clear_err: * drm_do_probe_ddc_edid, which bails out on the first -ENXIO. */ if (ret == -ENXIO && i == 0 && try++ == 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "GMBUS [%s] NAK on first message, retry\n", adapter->name); goto retry; @@ -701,10 +765,10 @@ clear_err: goto out; timeout: - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "GMBUS [%s] timed out, falling back to bit banging on pin %d\n", bus->adapter.name, bus->reg0 & 0xff); - intel_de_write_fw(dev_priv, GMBUS0, 0); + intel_de_write_fw(display, GMBUS0(display), 0); /* * Hardware may not support GMBUS over these pins? Try GPIO bitbanging @@ -713,11 +777,11 @@ timeout: ret = -EAGAIN; out: - /* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */ - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - bxt_gmbus_clock_gating(dev_priv, true); - else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv)) - pch_gmbus_clock_gating(dev_priv, true); + /* Display WA #0868: skl,bxt,kbl,cfl,glk */ + if (display->platform.geminilake || display->platform.broxton) + bxt_gmbus_clock_gating(display, true); + else if (HAS_PCH_SPT(display) || HAS_PCH_CNP(display)) + pch_gmbus_clock_gating(display, true); return ret; } @@ -725,13 +789,12 @@ out: static int gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) { - struct intel_gmbus *bus = - container_of(adapter, struct intel_gmbus, adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; + struct intel_gmbus *bus = to_intel_gmbus(adapter); + struct intel_display *display = bus->display; intel_wakeref_t wakeref; int ret; - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); + wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); if (bus->force_bit) { ret = i2c_bit_algo.master_xfer(adapter, msgs, num); @@ -743,18 +806,17 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) bus->force_bit |= GMBUS_FORCE_BIT_RETRY; } - intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); + intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); return ret; } int intel_gmbus_output_aksv(struct i2c_adapter *adapter) { - struct intel_gmbus *bus = - container_of(adapter, struct intel_gmbus, adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; + struct intel_gmbus *bus = to_intel_gmbus(adapter); + struct intel_display *display = bus->display; u8 cmd = DRM_HDCP_DDC_AKSV; - u8 buf[DRM_HDCP_KSV_LEN] = { 0 }; + u8 buf[DRM_HDCP_KSV_LEN] = {}; struct i2c_msg msgs[] = { { .addr = DRM_HDCP_DDC_ADDR, @@ -772,8 +834,8 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter) intel_wakeref_t wakeref; int ret; - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); - mutex_lock(&dev_priv->gmbus_mutex); + wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); + mutex_lock(&display->gmbus.mutex); /* * In order to output Aksv to the receiver, use an indexed write to @@ -782,8 +844,8 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter) */ ret = do_gmbus_xfer(adapter, msgs, ARRAY_SIZE(msgs), GMBUS_AKSV_SELECT); - mutex_unlock(&dev_priv->gmbus_mutex); - intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); + mutex_unlock(&display->gmbus.mutex); + intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); return ret; } @@ -806,27 +868,27 @@ static void gmbus_lock_bus(struct i2c_adapter *adapter, unsigned int flags) { struct intel_gmbus *bus = to_intel_gmbus(adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; + struct intel_display *display = bus->display; - mutex_lock(&dev_priv->gmbus_mutex); + mutex_lock(&display->gmbus.mutex); } static int gmbus_trylock_bus(struct i2c_adapter *adapter, unsigned int flags) { struct intel_gmbus *bus = to_intel_gmbus(adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; + struct intel_display *display = bus->display; - return mutex_trylock(&dev_priv->gmbus_mutex); + return mutex_trylock(&display->gmbus.mutex); } static void gmbus_unlock_bus(struct i2c_adapter *adapter, unsigned int flags) { struct intel_gmbus *bus = to_intel_gmbus(adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; + struct intel_display *display = bus->display; - mutex_unlock(&dev_priv->gmbus_mutex); + mutex_unlock(&display->gmbus.mutex); } static const struct i2c_lock_operations gmbus_lock_ops = { @@ -837,42 +899,47 @@ static const struct i2c_lock_operations gmbus_lock_ops = { /** * intel_gmbus_setup - instantiate all Intel i2c GMBuses - * @dev_priv: i915 device private + * @display: display device */ -int intel_gmbus_setup(struct drm_i915_private *dev_priv) +int intel_gmbus_setup(struct intel_display *display) { - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); - struct intel_gmbus *bus; + struct pci_dev *pdev = to_pci_dev(display->drm->dev); unsigned int pin; int ret; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - dev_priv->gpio_mmio_base = VLV_DISPLAY_BASE; - else if (!HAS_GMCH(dev_priv)) + if (display->platform.valleyview || display->platform.cherryview) + display->gmbus.mmio_base = VLV_DISPLAY_BASE; + else if (!HAS_GMCH(display)) /* * Broxton uses the same PCH offsets for South Display Engine, * even though it doesn't have a PCH. */ - dev_priv->gpio_mmio_base = PCH_DISPLAY_BASE; + display->gmbus.mmio_base = PCH_DISPLAY_BASE; - mutex_init(&dev_priv->gmbus_mutex); - init_waitqueue_head(&dev_priv->gmbus_wait_queue); + mutex_init(&display->gmbus.mutex); + init_waitqueue_head(&display->gmbus.wait_queue); - for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) { - if (!intel_gmbus_is_valid_pin(dev_priv, pin)) + for (pin = 0; pin < ARRAY_SIZE(display->gmbus.bus); pin++) { + const struct gmbus_pin *gmbus_pin; + struct intel_gmbus *bus; + + gmbus_pin = get_gmbus_pin(display, pin); + if (!gmbus_pin) continue; - bus = &dev_priv->gmbus[pin]; + bus = kzalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) { + ret = -ENOMEM; + goto err; + } bus->adapter.owner = THIS_MODULE; - bus->adapter.class = I2C_CLASS_DDC; snprintf(bus->adapter.name, sizeof(bus->adapter.name), - "i915 gmbus %s", - get_gmbus_pin(dev_priv, pin)->name); + "i915 gmbus %s", gmbus_pin->name); bus->adapter.dev.parent = &pdev->dev; - bus->dev_priv = dev_priv; + bus->display = display; bus->adapter.algo = &gmbus_algorithm; bus->adapter.lock_ops = &gmbus_lock_ops; @@ -887,62 +954,54 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv) bus->reg0 = pin | GMBUS_RATE_100KHZ; /* gmbus seems to be broken on i830 */ - if (IS_I830(dev_priv)) + if (display->platform.i830) bus->force_bit = 1; - intel_gpio_setup(bus, pin); + intel_gpio_setup(bus, GPIO(display, gmbus_pin->gpio)); ret = i2c_add_adapter(&bus->adapter); - if (ret) + if (ret) { + kfree(bus); goto err; + } + + display->gmbus.bus[pin] = bus; } - intel_gmbus_reset(dev_priv); + intel_gmbus_reset(display); return 0; err: - while (pin--) { - if (!intel_gmbus_is_valid_pin(dev_priv, pin)) - continue; + intel_gmbus_teardown(display); - bus = &dev_priv->gmbus[pin]; - i2c_del_adapter(&bus->adapter); - } return ret; } -struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, +struct i2c_adapter *intel_gmbus_get_adapter(struct intel_display *display, unsigned int pin) { - if (drm_WARN_ON(&dev_priv->drm, - !intel_gmbus_is_valid_pin(dev_priv, pin))) + if (drm_WARN_ON(display->drm, pin >= ARRAY_SIZE(display->gmbus.bus) || + !display->gmbus.bus[pin])) return NULL; - return &dev_priv->gmbus[pin].adapter; -} - -void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed) -{ - struct intel_gmbus *bus = to_intel_gmbus(adapter); - - bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | speed; + return &display->gmbus.bus[pin]->adapter; } void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit) { struct intel_gmbus *bus = to_intel_gmbus(adapter); - struct drm_i915_private *dev_priv = bus->dev_priv; + struct intel_display *display = bus->display; - mutex_lock(&dev_priv->gmbus_mutex); + mutex_lock(&display->gmbus.mutex); bus->force_bit += force_bit ? 1 : -1; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%sabling bit-banging on %s. force bit now %d\n", force_bit ? "en" : "dis", adapter->name, bus->force_bit); - mutex_unlock(&dev_priv->gmbus_mutex); + mutex_unlock(&display->gmbus.mutex); } bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter) @@ -952,16 +1011,25 @@ bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter) return bus->force_bit; } -void intel_gmbus_teardown(struct drm_i915_private *dev_priv) +void intel_gmbus_teardown(struct intel_display *display) { - struct intel_gmbus *bus; unsigned int pin; - for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) { - if (!intel_gmbus_is_valid_pin(dev_priv, pin)) + for (pin = 0; pin < ARRAY_SIZE(display->gmbus.bus); pin++) { + struct intel_gmbus *bus; + + bus = display->gmbus.bus[pin]; + if (!bus) continue; - bus = &dev_priv->gmbus[pin]; i2c_del_adapter(&bus->adapter); + + kfree(bus); + display->gmbus.bus[pin] = NULL; } } + +void intel_gmbus_irq_handler(struct intel_display *display) +{ + wake_up_all(&display->gmbus.wait_queue); +} |
