aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_i2c.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-05-08 06:51:06 -0400
committerDave Airlie <airlied@redhat.com>2015-05-08 06:51:06 -0400
commite1dee1973c74a0408b108d88c57a15be8a2d6d84 (patch)
tree91cab9c1bf02907c294eb141c62102dcd806bdd1 /drivers/gpu/drm/i915/intel_i2c.c
parentc0fe07aa50befe2e6e6525181e2080377a1c1494 (diff)
parent93a96c6f049d047bc196890fc4284eff15b3770f (diff)
Merge tag 'drm-intel-next-2015-04-23-fixed' of git://anongit.freedesktop.org/drm-intel into drm-next
drm-intel-next-2015-04-23: - dither support for ns2501 dvo (Thomas Richter) - some polish for the gtt code and fixes to finally enable the cmd parser on hsw - first pile of bxt stage 1 enabling (too many different people to list ...) - more psr fixes from Rodrigo - skl rotation support from Chandra - more atomic work from Ander and Matt - pile of cleanups and micro-ops for execlist from Chris drm-intel-next-2015-04-10: - cdclk handling cleanup and fixes from Ville - more prep patches for olr removal from John Harrison - gmbus pin naming rework from Jani (prep for bxt) - remove ->new_config from Ander (more atomic conversion work) - rps (boost) tuning and unification with byt/bsw from Chris - cmd parser batch bool tuning from Chris - gen8 dynamic pte allocation (Michel Thierry, based on work from Ben Widawsky) - execlist tuning (not yet all of it) from Chris - add drm_plane_from_index (Chandra) - various small things all over * tag 'drm-intel-next-2015-04-23-fixed' of git://anongit.freedesktop.org/drm-intel: (204 commits) drm/i915/gtt: Allocate va range only if vma is not bound drm/i915: Enable cmd parser to do secure batch promotion for aliasing ppgtt drm/i915: fix intel_prepare_ddi drm/i915: factor out ddi_get_encoder_port drm/i915/hdmi: check port in ibx_infoframe_enabled drm/i915/hdmi: fix vlv infoframe port check drm/i915: Silence compiler warning in dvo drm/i915: Update DRIVER_DATE to 20150423 drm/i915: Enable dithering on NatSemi DVO2501 for Fujitsu S6010 rm/i915: Move i915_get_ggtt_vma_pages into ggtt_bind_vma drm/i915: Don't try to outsmart gcc in i915_gem_gtt.c drm/i915: Unduplicate i915_ggtt_unbind/bind_vma drm/i915: Move ppgtt_bind/unbind around drm/i915: move i915_gem_restore_gtt_mappings around drm/i915: Fix up the vma aliasing ppgtt binding drm/i915: Remove misleading comment around bind_to_vm drm/i915: Don't use atomics for pg_dirty_rings drm/i915: Don't look at pg_dirty_rings for aliasing ppgtt drm/i915/skl: Support Y tiling in MMIO flips drm/i915: Fixup kerneldoc for struct intel_context ... Conflicts: drivers/gpu/drm/i915/i915_drv.c
Diffstat (limited to 'drivers/gpu/drm/i915/intel_i2c.c')
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c97
1 files changed, 69 insertions, 28 deletions
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 56e437e31580..3daa7e322326 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -34,20 +34,50 @@
34#include <drm/i915_drm.h> 34#include <drm/i915_drm.h>
35#include "i915_drv.h" 35#include "i915_drv.h"
36 36
37struct gmbus_port { 37struct gmbus_pin {
38 const char *name; 38 const char *name;
39 int reg; 39 int reg;
40}; 40};
41 41
42static const struct gmbus_port gmbus_ports[] = { 42/* Map gmbus pin pairs to names and registers. */
43 { "ssc", GPIOB }, 43static const struct gmbus_pin gmbus_pins[] = {
44 { "vga", GPIOA }, 44 [GMBUS_PIN_SSC] = { "ssc", GPIOB },
45 { "panel", GPIOC }, 45 [GMBUS_PIN_VGADDC] = { "vga", GPIOA },
46 { "dpc", GPIOD }, 46 [GMBUS_PIN_PANEL] = { "panel", GPIOC },
47 { "dpb", GPIOE }, 47 [GMBUS_PIN_DPC] = { "dpc", GPIOD },
48 { "dpd", GPIOF }, 48 [GMBUS_PIN_DPB] = { "dpb", GPIOE },
49 [GMBUS_PIN_DPD] = { "dpd", GPIOF },
49}; 50};
50 51
52static const struct gmbus_pin gmbus_pins_bxt[] = {
53 [GMBUS_PIN_1_BXT] = { "dpb", PCH_GPIOB },
54 [GMBUS_PIN_2_BXT] = { "dpc", PCH_GPIOC },
55 [GMBUS_PIN_3_BXT] = { "misc", PCH_GPIOD },
56};
57
58/* pin is expected to be valid */
59static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *dev_priv,
60 unsigned int pin)
61{
62 if (IS_BROXTON(dev_priv))
63 return &gmbus_pins_bxt[pin];
64 else
65 return &gmbus_pins[pin];
66}
67
68bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
69 unsigned int pin)
70{
71 unsigned int size;
72
73 if (IS_BROXTON(dev_priv))
74 size = ARRAY_SIZE(gmbus_pins_bxt);
75 else
76 size = ARRAY_SIZE(gmbus_pins);
77
78 return pin < size && get_gmbus_pin(dev_priv, pin)->reg;
79}
80
51/* Intel GPIO access functions */ 81/* Intel GPIO access functions */
52 82
53#define I2C_RISEFALL_TIME 10 83#define I2C_RISEFALL_TIME 10
@@ -182,15 +212,15 @@ intel_gpio_post_xfer(struct i2c_adapter *adapter)
182} 212}
183 213
184static void 214static void
185intel_gpio_setup(struct intel_gmbus *bus, u32 pin) 215intel_gpio_setup(struct intel_gmbus *bus, unsigned int pin)
186{ 216{
187 struct drm_i915_private *dev_priv = bus->dev_priv; 217 struct drm_i915_private *dev_priv = bus->dev_priv;
188 struct i2c_algo_bit_data *algo; 218 struct i2c_algo_bit_data *algo;
189 219
190 algo = &bus->bit_algo; 220 algo = &bus->bit_algo;
191 221
192 /* -1 to map pin pair to gmbus index */ 222 bus->gpio_reg = dev_priv->gpio_mmio_base +
193 bus->gpio_reg = dev_priv->gpio_mmio_base + gmbus_ports[pin - 1].reg; 223 get_gmbus_pin(dev_priv, pin)->reg;
194 224
195 bus->adapter.algo_data = algo; 225 bus->adapter.algo_data = algo;
196 algo->setsda = set_data; 226 algo->setsda = set_data;
@@ -563,7 +593,9 @@ static const struct i2c_algorithm gmbus_algorithm = {
563int intel_setup_gmbus(struct drm_device *dev) 593int intel_setup_gmbus(struct drm_device *dev)
564{ 594{
565 struct drm_i915_private *dev_priv = dev->dev_private; 595 struct drm_i915_private *dev_priv = dev->dev_private;
566 int ret, i; 596 struct intel_gmbus *bus;
597 unsigned int pin;
598 int ret;
567 599
568 if (HAS_PCH_NOP(dev)) 600 if (HAS_PCH_NOP(dev))
569 return 0; 601 return 0;
@@ -577,16 +609,18 @@ int intel_setup_gmbus(struct drm_device *dev)
577 mutex_init(&dev_priv->gmbus_mutex); 609 mutex_init(&dev_priv->gmbus_mutex);
578 init_waitqueue_head(&dev_priv->gmbus_wait_queue); 610 init_waitqueue_head(&dev_priv->gmbus_wait_queue);
579 611
580 for (i = 0; i < GMBUS_NUM_PORTS; i++) { 612 for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
581 struct intel_gmbus *bus = &dev_priv->gmbus[i]; 613 if (!intel_gmbus_is_valid_pin(dev_priv, pin))
582 u32 port = i + 1; /* +1 to map gmbus index to pin pair */ 614 continue;
615
616 bus = &dev_priv->gmbus[pin];
583 617
584 bus->adapter.owner = THIS_MODULE; 618 bus->adapter.owner = THIS_MODULE;
585 bus->adapter.class = I2C_CLASS_DDC; 619 bus->adapter.class = I2C_CLASS_DDC;
586 snprintf(bus->adapter.name, 620 snprintf(bus->adapter.name,
587 sizeof(bus->adapter.name), 621 sizeof(bus->adapter.name),
588 "i915 gmbus %s", 622 "i915 gmbus %s",
589 gmbus_ports[i].name); 623 get_gmbus_pin(dev_priv, pin)->name);
590 624
591 bus->adapter.dev.parent = &dev->pdev->dev; 625 bus->adapter.dev.parent = &dev->pdev->dev;
592 bus->dev_priv = dev_priv; 626 bus->dev_priv = dev_priv;
@@ -594,13 +628,13 @@ int intel_setup_gmbus(struct drm_device *dev)
594 bus->adapter.algo = &gmbus_algorithm; 628 bus->adapter.algo = &gmbus_algorithm;
595 629
596 /* By default use a conservative clock rate */ 630 /* By default use a conservative clock rate */
597 bus->reg0 = port | GMBUS_RATE_100KHZ; 631 bus->reg0 = pin | GMBUS_RATE_100KHZ;
598 632
599 /* gmbus seems to be broken on i830 */ 633 /* gmbus seems to be broken on i830 */
600 if (IS_I830(dev)) 634 if (IS_I830(dev))
601 bus->force_bit = 1; 635 bus->force_bit = 1;
602 636
603 intel_gpio_setup(bus, port); 637 intel_gpio_setup(bus, pin);
604 638
605 ret = i2c_add_adapter(&bus->adapter); 639 ret = i2c_add_adapter(&bus->adapter);
606 if (ret) 640 if (ret)
@@ -612,20 +646,23 @@ int intel_setup_gmbus(struct drm_device *dev)
612 return 0; 646 return 0;
613 647
614err: 648err:
615 while (--i) { 649 while (--pin) {
616 struct intel_gmbus *bus = &dev_priv->gmbus[i]; 650 if (!intel_gmbus_is_valid_pin(dev_priv, pin))
651 continue;
652
653 bus = &dev_priv->gmbus[pin];
617 i2c_del_adapter(&bus->adapter); 654 i2c_del_adapter(&bus->adapter);
618 } 655 }
619 return ret; 656 return ret;
620} 657}
621 658
622struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, 659struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
623 unsigned port) 660 unsigned int pin)
624{ 661{
625 WARN_ON(!intel_gmbus_is_port_valid(port)); 662 if (WARN_ON(!intel_gmbus_is_valid_pin(dev_priv, pin)))
626 /* -1 to map pin pair to gmbus index */ 663 return NULL;
627 return (intel_gmbus_is_port_valid(port)) ? 664
628 &dev_priv->gmbus[port - 1].adapter : NULL; 665 return &dev_priv->gmbus[pin].adapter;
629} 666}
630 667
631void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed) 668void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed)
@@ -648,10 +685,14 @@ void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
648void intel_teardown_gmbus(struct drm_device *dev) 685void intel_teardown_gmbus(struct drm_device *dev)
649{ 686{
650 struct drm_i915_private *dev_priv = dev->dev_private; 687 struct drm_i915_private *dev_priv = dev->dev_private;
651 int i; 688 struct intel_gmbus *bus;
689 unsigned int pin;
690
691 for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
692 if (!intel_gmbus_is_valid_pin(dev_priv, pin))
693 continue;
652 694
653 for (i = 0; i < GMBUS_NUM_PORTS; i++) { 695 bus = &dev_priv->gmbus[pin];
654 struct intel_gmbus *bus = &dev_priv->gmbus[i];
655 i2c_del_adapter(&bus->adapter); 696 i2c_del_adapter(&bus->adapter);
656 } 697 }
657} 698}