[haiku-commits] r42740 - haiku/trunk/src/add-ons/accelerants/radeon_hd

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 11 Sep 2011 20:20:42 +0200 (CEST)

Author: kallisti5
Date: 2011-09-11 20:20:41 +0200 (Sun, 11 Sep 2011)
New Revision: 42740
Changeset: https://dev.haiku-os.org/changeset/42740

Modified:
   haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.cpp
Log:
* refactor GPU i2c bit-banging code to be correct using drm as reference
* add i2c locking code that represents common things we need to do before
  and after access


Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h  2011-09-11 
17:15:14 UTC (rev 42739)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/accelerant.h  2011-09-11 
18:20:41 UTC (rev 42740)
@@ -140,6 +140,8 @@
 
 struct ddc_info {
        bool    valid;
+       bool    hw_capable;
+
        uint8   gpio_id;
 
        uint16  mask_scl_reg;

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.cpp       2011-09-11 
17:15:14 UTC (rev 42739)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/gpu.cpp       2011-09-11 
18:20:41 UTC (rev 42740)
@@ -277,35 +277,67 @@
 }
 
 
+static void
+lock_i2c(void* cookie, bool lock)
+{
+       ddc_info *info = (ddc_info*)cookie;
+
+       uint32 buffer = 0;
+
+       if (info->hw_capable == true) {
+               // Switch GPIO pads to ddc mode
+               buffer = Read32(OUT, info->mask_scl_reg);
+               buffer &= ~(1 << 16);
+               Write32(OUT, info->mask_scl_reg, buffer);
+       }
+
+       // Clear pins
+       buffer = Read32(OUT, info->gpio_a_scl_reg) & ~info->gpio_a_scl_shift;
+       Write32(OUT, info->gpio_a_scl_reg, buffer);
+       buffer = Read32(OUT, info->gpio_a_sda_reg) & ~info->gpio_a_sda_shift;
+       Write32(OUT, info->gpio_a_sda_reg, buffer);
+
+       // Set pins to input
+       buffer = Read32(OUT, info->gpio_en_scl_reg) & ~info->gpio_en_scl_shift;
+       Write32(OUT, info->gpio_en_scl_reg, buffer);
+       buffer = Read32(OUT, info->gpio_en_sda_reg) & ~info->gpio_en_sda_shift;
+       Write32(OUT, info->gpio_en_sda_reg, buffer);
+
+       // mask GPIO pins for software use
+       buffer = Read32(OUT, info->mask_scl_reg);
+       if (lock == true)
+               buffer |= info->mask_scl_shift;
+       else
+               buffer &= ~info->mask_scl_shift;
+       Write32(OUT, info->mask_scl_reg, buffer);
+       Read32(OUT, info->mask_scl_reg);
+
+       buffer = Read32(OUT, info->mask_sda_reg);
+       if (lock == true)
+               buffer |= info->mask_sda_shift;
+       else
+               buffer &= ~info->mask_sda_shift;
+       Write32(OUT, info->mask_sda_reg, buffer);
+       Read32(OUT, info->mask_sda_reg);
+}
+
+
 static status_t
 get_i2c_signals(void* cookie, int* _clock, int* _data)
 {
        ddc_info *info = (ddc_info*)cookie;
 
-       // software only access
-       //uint32 scl_maskVal = Read32(OUT, info->mask_scl_reg);
-       //uint32 sda_maskVal = Read32(OUT, info->mask_sda_reg);
-       //Write32(OUT, info->mask_scl_reg, 1);
-       //Write32(OUT, info->mask_sda_reg, 1);
+       lock_i2c(cookie, true);
+       uint32 scl = Read32(OUT, info->gpio_y_scl_reg) & info->gpio_y_scl_shift;
+       uint32 sda = Read32(OUT, info->gpio_y_sda_reg) & info->gpio_y_sda_shift;
+       lock_i2c(cookie, false);
 
-       // set read mode
-       uint32 scl_enVal = Read32(OUT, info->gpio_en_scl_reg);
-       uint32 sda_enVal = Read32(OUT, info->gpio_en_sda_reg);
-       Write32(OUT, info->gpio_en_scl_reg, 0);
-       Write32(OUT, info->gpio_en_sda_reg, 0);
+       *_clock = (scl != 0);
+       *_data = (sda != 0);
 
-       *_clock = Read32(OUT, info->gpio_y_scl_reg);
-       *_data = Read32(OUT, info->gpio_y_sda_reg);
-
        TRACE("%s: GPIO 0x%" B_PRIX8 ", clock: %d, data: %d\n",
                __func__, info->gpio_id, *_clock, *_data);
 
-       // restore previous settings
-       //Write32(OUT, info->mask_scl_reg, scl_maskVal);
-       //Write32(OUT, info->mask_sda_reg, sda_maskVal);
-       Write32(OUT, info->gpio_en_scl_reg, scl_enVal);
-       Write32(OUT, info->gpio_en_sda_reg, sda_enVal);
-
        return B_OK;
 }
 
@@ -315,34 +347,22 @@
 {
        ddc_info* info = (ddc_info*)cookie;
 
-       // software only access
-       uint32 scl_maskVal = Read32(OUT, info->mask_scl_reg);
-       uint32 sda_maskVal = Read32(OUT, info->mask_sda_reg);
-       Write32(OUT, info->mask_scl_reg, 1);
-       Write32(OUT, info->mask_sda_reg, 1);
+       lock_i2c(cookie, true);
+       uint32 scl = Read32(OUT, info->gpio_en_scl_reg)
+               & ~info->gpio_en_scl_shift;
+       uint32 sda = Read32(OUT, info->gpio_en_sda_reg)
+               & ~info->gpio_en_sda_shift;
 
-       // set write mode
-       uint32 scl_enVal = Read32(OUT, info->gpio_en_scl_reg);
-       uint32 sda_enVal = Read32(OUT, info->gpio_en_sda_reg);
-       Write32(OUT, info->gpio_en_scl_reg, 1);
-       Write32(OUT, info->gpio_en_sda_reg, 1);
+       scl |= clock ? 0 : info->gpio_en_scl_shift;
+       sda |= data ? 0 : info->gpio_en_sda_shift;
 
        Write32(OUT, info->gpio_a_scl_reg, clock);
        Write32(OUT, info->gpio_a_sda_reg, data);
+       lock_i2c(cookie, false);
 
-       // read back to improve reliability?
-       Read32(OUT, info->gpio_a_scl_reg);
-       Read32(OUT, info->gpio_a_sda_reg);
-
        TRACE("%s: GPIO 0x%" B_PRIX8 ", clock: %d, data: %d\n",
                __func__, info->gpio_id, clock, data);
 
-       // restore previous settings
-       Write32(OUT, info->mask_scl_reg, scl_maskVal);
-       Write32(OUT, info->mask_sda_reg, sda_maskVal);
-       Write32(OUT, info->gpio_en_scl_reg, scl_enVal);
-       Write32(OUT, info->gpio_en_sda_reg, sda_enVal);
-
        return B_OK;
 }
 
@@ -417,6 +437,13 @@
 
                // populate gpio information
                gConnector[connector]->connector_ddc_info.valid = true;
+
+               // TODO : what is hw_capable?
+               if (gpio->sucI2cId.sbfAccess.bfHW_Capable)
+                       gConnector[connector]->connector_ddc_info.hw_capable = 
true;
+               else
+                       gConnector[connector]->connector_ddc_info.hw_capable = 
true;
+
                gConnector[connector]->connector_ddc_info.gpio_id = gpio_id;
 
                // GPIO mask (Allows software to control the GPIO pad)


Other related posts:

  • » [haiku-commits] r42740 - haiku/trunk/src/add-ons/accelerants/radeon_hd - kallisti5