PMU: patch from umg kernel 2.6.35 tree
authorFei Yang <fei.yang@intel.com>
Thu, 25 Aug 2011 21:07:05 +0000 (14:07 -0700)
committermgross <mark.gross@intel.com>
Wed, 9 Nov 2011 20:37:29 +0000 (12:37 -0800)
commit d0378332f33fbee63f6e5b5f44dd9b64c53c5525
Author: Bin Gao <bin.gao@intel.com>
Date:   Fri Aug 12 10:44:11 2011 -0700

    mid_pmu: add NC device power island state to mid_pmu debugfs interface

    BZ:  7322

    Currently mid_pmu debugfs interface("mid_pmu_states") only shows
    power state of PCI devices in SC. For NC devices(display, camera,
    etc.), there are just two simple variables display_off and
    camera_off to track the current power status, but for both display
    and camera, there are more than one power islands, for debug purpose,
    we need present all these power islands states to debugfs interface.

    This patch adds:
    GFX, Decoder, Encoder, GL3, Display A/B/C and MIPI-DSI
    island state to gfx/display device(00:02.0), and,
    ISP and Iunit PHY island state to isp device(00:03.0).

    Change-Id: If93f346c16b6a1a39462aff9920167c2e06c32ef
Signed-off-by: Bin Gao <bin.gao@intel.com>
Change-Id: If7f398e032f7b653a39fd91a74cea5be443a562f
Signed-off-by: Fei Yang <fei.yang@intel.com>
arch/x86/platform/mfld/pmu.c

index a48b531..bd72ff0 100755 (executable)
@@ -1547,6 +1547,104 @@ ret:
 }
 
 #ifdef CONFIG_DEBUG_FS
+static int pmu_nc_get_power_state(int island, int reg_type)
+{
+       u32 pwr_sts;
+       unsigned long flags;
+       int i, lss;
+       int ret = -EINVAL;
+
+       spin_lock_irqsave(&nc_ready_lock, flags);
+
+       switch (reg_type) {
+       case APM_REG_TYPE:
+               pwr_sts = inl(apm_base + APM_STS);
+               break;
+       case OSPM_REG_TYPE:
+               pwr_sts = inl(ospm_base + OSPM_PM_SSS);
+               break;
+       default:
+               pr_err("%s: invalid argument 'island': %d.\n",
+                                __func__, island);
+               goto unlock;
+       }
+
+       for (i = 0; i < OSPM_MAX_POWER_ISLANDS; i++) {
+               lss = island & (0x1 << i);
+               if (lss) {
+                       ret = (pwr_sts >> (2 * i)) & 0x3;
+                       break;
+               }
+       }
+
+unlock:
+       spin_unlock_irqrestore(&nc_ready_lock, flags);
+       return ret;
+}
+
+#define DEV_GFX                2
+#define FUNC_GFX       0
+#define ISLANDS_GFX    8
+#define DEV_ISP                3
+#define FUNC_ISP       0
+#define ISLANDS_ISP    2
+#define NC_DEVS                2
+
+struct island {
+       int type;
+       int index;
+       char *name;
+};
+
+static struct island display_islands[] = {
+       {APM_REG_TYPE, APM_GRAPHICS_ISLAND, "GFX"},
+       {APM_REG_TYPE, APM_VIDEO_DEC_ISLAND, "Video Decoder"},
+       {APM_REG_TYPE, APM_VIDEO_ENC_ISLAND, "Video Encoder"},
+       {APM_REG_TYPE, APM_GL3_CACHE_ISLAND, "GL3 Cache"},
+       {OSPM_REG_TYPE, OSPM_DISPLAY_A_ISLAND, "Display A"},
+       {OSPM_REG_TYPE, OSPM_DISPLAY_B_ISLAND, "Display B"},
+       {OSPM_REG_TYPE, OSPM_DISPLAY_C_ISLAND, "Display C"},
+       {OSPM_REG_TYPE, OSPM_MIPI_ISLAND, "MIPI-DSI"}
+};
+
+static struct island camera_islands[] = {
+       {APM_REG_TYPE, APM_ISP_ISLAND, "ISP"},
+       {APM_REG_TYPE, APM_IPH_ISLAND, "Iunit PHY"}
+};
+
+static void nc_device_state_show(struct seq_file *s, struct pci_dev *pdev)
+{
+       int off, i, islands_num, state;
+       struct island *islands;
+       char *dstates[] = {"D0", "D0i1", "D0i2", "D0i3"};
+
+       if (PCI_SLOT(pdev->devfn) == DEV_GFX &&
+                       PCI_FUNC(pdev->devfn) == FUNC_GFX) {
+               off = display_off;
+               islands_num = ISLANDS_GFX;
+               islands = &display_islands[0];
+       } else if (PCI_SLOT(pdev->devfn) == DEV_ISP &&
+                       PCI_FUNC(pdev->devfn) == FUNC_ISP) {
+               off = camera_off;
+               islands_num = ISLANDS_ISP;
+               islands = &camera_islands[0];
+       } else {
+               return;
+       }
+
+       seq_printf(s, "pci %04x %04X %s %20s: %41s %s\n",
+               pdev->vendor, pdev->device, dev_name(&pdev->dev),
+               dev_driver_string(&pdev->dev),
+               "", off ? "" : "blocking s0ix");
+       for (i = 0; i < islands_num; i++) {
+               state = pmu_nc_get_power_state(islands[i].index,
+                               islands[i].type);
+               seq_printf(s, "%52s %15s %17s %s\n",
+                                "|------->", islands[i].name, "",
+                               (state >= 0) ? dstates[state] : "ERR");
+       }
+}
+
 static int pmu_devices_state_show(struct seq_file *s, void *unused)
 {
        struct pci_dev *pdev = NULL;
@@ -1618,8 +1716,10 @@ static int pmu_devices_state_show(struct seq_file *s, void *unused)
                                                                  &ss_pos))
                        continue;
 
-               if (pmu_num == PMU_NUM_1)
+               if (pmu_num == PMU_NUM_1) {
+                       nc_device_state_show(s, pdev);
                        continue;
+               }
 
                mask    = (D0I3_MASK << (ss_pos * BITS_PER_LSS));
                val     = (cur_pmsss.pmu2_states[ss_idx] & mask) >>