dra7xx-evm: weston: add changes for AGL home screen 41/7241/2
authorKarthik Ramanan <a0393906@ti.com>
Fri, 18 Nov 2016 07:47:53 +0000 (13:17 +0530)
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Tue, 22 Nov 2016 16:32:17 +0000 (16:32 +0000)
This patch set contains three sets of changes:
 * Recipes and patches from meta-arago for weston bringup
 * Additional patches to support ivi-shell for dra7xx-evm
 * Configuration settings for applications/AGL home screen

Change-Id: I925c1babdf2e825c0f68ec1d57107469f3abef09
Signed-off-by: Karthik Ramanan <a0393906@ti.com>
23 files changed:
meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init.bbappend [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init/init [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init/runWeston [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-Add-soc-performance-monitor-utilites.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-Add-autolaunch-and-launch-rules-functional.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-Add-screenshooter-option.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-fix-TODO-which-expects-only-one-screen-in-.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-layer-controller-ti-Improve-functionality.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-udev-seat-restrict-udev-enumeration-to-card0.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-weston1.9.0-Enabling-DRM-backend-with-multiple-displ.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0002-Weston1.9.0-Allow-visual_id-to-be-0.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0002-ivi-shell-multi-screen-support-to-calcuration-of-a-m.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0003-Weston1.9.0-Fix-virtual-keyboard-display-issue-for-Q.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0003-ivi-shell-avoid-update_prop-on-invisible-surfaces.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0004-Weston1.9.0-Fix-touch-screen-crash-issue.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0004-ivi-shell-fix-layout_layer.view_list-is-not-initiliz.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0005-ivi-shell-convert-from-screen-to-global-coordinates.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0006-ivi-shell-remove-a-code-which-expects-only-a-screen-.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0007-ivi-shell-layout-Export-surface-destroy-callback.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/dra7xx-evm/weston.ini [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston/weston.service [new file with mode: 0644]
meta-agl-bsp/meta-ti/recipes-arago/weston/weston_1.9.0.bbappend [new file with mode: 0644]

diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init.bbappend b/meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init.bbappend
new file mode 100644 (file)
index 0000000..041e5ab
--- /dev/null
@@ -0,0 +1,15 @@
+PR_append = ".arago7"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI_append = " \
+    file://runWeston \
+"
+
+do_install_append() {
+    install -d ${D}${bindir}
+    install -m 755 ${WORKDIR}/runWeston ${D}${bindir}
+    rm -rf ${D}${systemd_system_unitdir}
+}
+
+SYSTEMD_SERVICE_${PN} = ""
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init/init b/meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init/init
new file mode 100644 (file)
index 0000000..336e5af
--- /dev/null
@@ -0,0 +1,108 @@
+#!/bin/sh
+#
+### BEGIN INIT INFO
+# Provides: weston
+# Required-Start: $local_fs $remote_fs
+# Required-Stop: $local_fs $remote_fs
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+### END INIT INFO
+
+killproc() {
+        pid=`/bin/pidof $1`
+        [ "$pid" != "" ] && kill $pid
+}
+
+read CMDLINE < /proc/cmdline
+for x in $CMDLINE; do
+        case $x in
+        weston=false)
+               echo "Weston disabled"
+               exit 0;
+                ;;
+        esac
+done
+
+case "$1" in
+  start)
+        . /etc/profile
+
+        # Weston for some reason dies if these environment variables are set
+        unset WAYLAND_DISPLAY
+
+        # This is all a nasty hack
+        if test -z "$XDG_RUNTIME_DIR"; then
+            export XDG_RUNTIME_DIR=/run/user/root
+        fi
+
+        if [ ! -d "$XDG_RUNTIME_DIR" ] ; then
+            mkdir --parents $XDG_RUNTIME_DIR
+            chmod 0700 $XDG_RUNTIME_DIR
+        fi
+
+        openvt -c 4 -f runWeston
+
+        # If there's no touchscreen device available, done
+        if [ ! -e /dev/input/touchscreen0 ] ; then
+            exit 0
+        fi
+
+        # If it was already calibrated, done
+        if [ -f "$WS_CALUDEV_FILE" ] ; then
+            exit 0
+        fi
+
+        # Check if SD card is mounted
+        mount | grep /run/media/mmcblk0p1 | grep vfat > /dev/null 2>&1
+        if [ "$?" = "0" ] ; then
+            SD_MOUNTED="1"
+        else
+            SD_MOUNTED="0"
+        fi
+
+        # Check if SD card has a calibration rules file
+        SD_CALUDEV_FILE=/run/media/mmcblk0p1/ws-calibrate.rules
+        if [ "$SD_MOUNTED" = "1" -a -f "$SD_CALUDEV_FILE" ] ; then
+            # Copy it over to udev location
+            cp "$SD_CALUDEV_FILE" "$WS_CALUDEV_FILE"
+        else
+            # Run a calibration app and save output to udev rules
+            echo    "Calibrating touchscreen (first time only)"
+            echo
+            echo    "*** To continue, please complete the touchscreen calibration"
+            echo -n "*** by touching the crosshairs on the LCD screen"
+            sleep 1
+            CAL_VALUES=`weston-calibrator|cut -c21-`
+            echo 'SUBSYSTEM=="input", ENV{WL_CALIBRATION}="'$CAL_VALUES'"' > $WS_CALUDEV_FILE
+            echo "."
+            # Copy it back to SD
+            if [ "$SD_MOUNTED" = "1" ] ; then
+                cp "$WS_CALUDEV_FILE" "$SD_CALUDEV_FILE"
+            fi
+        fi
+
+        # Reload and re-run udev rules and restart weston
+        udevadm control --reload
+        udevadm trigger
+        killproc weston
+        sleep 2
+        openvt -c 4 -f runWeston
+  ;;
+
+  stop)
+        echo "Stopping Weston"
+        killproc weston
+  ;;
+
+  restart)
+       $0 stop
+        sleep 2
+        $0 start
+  ;;
+
+  *)
+        echo "usage: $0 { start | stop | restart }"
+  ;;
+esac
+
+exit 0
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init/runWeston b/meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init/runWeston
new file mode 100644 (file)
index 0000000..aed5d5f
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+clear
+cat << EOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                        Please wait...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+EOF
+
+weston --idle-time=0 >> /var/log/weston.log 2>&1
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-Add-soc-performance-monitor-utilites.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-Add-soc-performance-monitor-utilites.patch
new file mode 100644 (file)
index 0000000..751a7ce
--- /dev/null
@@ -0,0 +1,3565 @@
+From 7830118ecb980766f4a6e3997769d7ae326bee77 Mon Sep 17 00:00:00 2001
+From: Karthik Ramanan <a0393906@ti.com>
+Date: Fri, 3 Jun 2016 18:32:50 +0530
+Subject: [PATCH] Add soc performance monitor utilites
+
+Signed-off-by: Karthik Ramanan <a0393906@ti.com>
+---
+ Makefile.am                       |   17 +-
+ clients/Dra7xx_ddrstat_speed.c    |  494 +++++++++++++
+ clients/soc_performance_monitor.c |  625 ++++++++++++++++
+ clients/soc_performance_monitor.h |   40 ++
+ clients/statcoll.c                | 1433 +++++++++++++++++++++++++++++++++++++
+ clients/statcoll.h                |  152 ++++
+ clients/statcoll_gui.h            |  101 +++
+ clients/time_bar_graph.c          |  515 +++++++++++++
+ clients/time_bar_graph.h          |   93 +++
+ 10 files changed, 4873 insertions(+), 1 deletion(-)
+ create mode 100644 clients/Dra7xx_ddrstat_speed.c
+ create mode 100644 clients/soc_performance_monitor.c
+ create mode 100644 clients/soc_performance_monitor.h
+ create mode 100644 clients/statcoll.c
+ create mode 100644 clients/statcoll.h
+ create mode 100644 clients/statcoll_gui.h
+ create mode 100644 clients/time_bar_graph.c
+ create mode 100644 clients/time_bar_graph.h
+
+diff --git a/Makefile.am b/Makefile.am
+index 62719c9..55aed6d 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -432,7 +432,9 @@ demo_clients =                                     \
+       weston-fullscreen                       \
+       weston-stacking                         \
+       weston-calibrator                       \
+-      weston-scaler
++      weston-scaler                           \
++      soc-performance-monitor                 \
++      soc-ddr-bw-visualizer
+ if INSTALL_DEMO_CLIENTS
+ bin_PROGRAMS += $(demo_clients)
+@@ -570,6 +572,19 @@ weston_image_SOURCES = clients/image.c
+ weston_image_LDADD = libtoytoolkit.la
+ weston_image_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
++noinst_LTLIBRARIES += libtimebargraph.la
++libtimebargraph_la_SOURCES = clients/time_bar_graph.c clients/time_bar_graph.h
++libtimebargraph_la_LIBADD = libtoytoolkit.la
++libtimebargraph_la_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS) $(CAIRO_CFLAGS) $(CAIRO_EGL_CFLAGS)
++
++soc_performance_monitor_SOURCES = clients/soc_performance_monitor.c clients/soc_performance_monitor.h 
++soc_performance_monitor_LDADD = libtoytoolkit.la libtimebargraph.la
++soc_performance__CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
++
++soc_ddr_bw_visualizer_SOURCES = clients/statcoll.c clients/Dra7xx_ddrstat_speed.c  clients/statcoll.h clients/statcoll_gui.h 
++soc_ddr_bw_visualizer_LDADD = libtoytoolkit.la libtimebargraph.la 
++soc_ddr_bw_visualizer__CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
++
+ weston_cliptest_SOURCES =                             \
+       clients/cliptest.c                              \
+       src/vertex-clipping.c                           \
+diff --git a/clients/Dra7xx_ddrstat_speed.c b/clients/Dra7xx_ddrstat_speed.c
+new file mode 100644
+index 0000000..af06733
+--- /dev/null
++++ b/clients/Dra7xx_ddrstat_speed.c
+@@ -0,0 +1,494 @@
++/*
++ * Copyright (C) 2015 Texas Instruments
++ * Author: Karthik Ramanan <karthik.ramanan@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <string.h>
++#include <sys/mman.h>
++#include <sys/time.h>
++#include <unistd.h>
++#include <fcntl.h>
++#include "statcoll.h"
++
++#define PAGE_SIZE 4096
++
++#define EMIF1_BASE 0x4c000000
++#define EMIF2_BASE 0x4d000000
++
++#define EMIF_PERF_CNT_1     0x80
++#define EMIF_PERF_CNT_2     0x84
++#define EMIF_PERF_CNT_CFG   0x88
++#define EMIF_PERF_CNT_TIM   0x90
++
++static unsigned
++tv_diff(struct timeval *tv1, struct timeval *tv2)
++{
++    return (tv2->tv_sec - tv1->tv_sec) * 1000000 +
++        (tv2->tv_usec - tv1->tv_usec);
++}
++
++
++struct emif_perf {
++    int code;
++    const char *name;
++};
++
++static const struct emif_perf emif_perf_tab[] = {
++    {  0, "access"     },
++    {  1, "activate"   },
++    {  2, "read"       },
++    {  3, "write"      },
++    {  4, "fifo_cmd"   },
++    {  5, "fifo_write" },
++    {  6, "fifo_read"  },
++    {  7, "fifo_ret"   },
++    {  8, "prio"       },
++    {  9, "cmd_pend"   },
++    { 10, "data"       },
++};
++
++static void *emif1, *emif2;
++static int BANDWIDTH=0;
++static int DELAY = 1;
++static int EMIF_PERF_CFG1 = 9;
++static int EMIF_PERF_CFG2 = 10;
++
++
++static int STATCOLL=0;
++static int TOTAL_TIME;
++static int INTERVAL_US;
++
++struct timeval t1, t2;
++
++FILE* outfile;
++struct emif_stats {
++    uint32_t cycles;
++    uint32_t cnt1;
++    uint32_t cnt2;
++};
++
++static struct emif_stats emif1_start, emif1_end;
++static struct emif_stats emif2_start, emif2_end;
++
++static void *emif_init(int fd, unsigned base)
++{
++    void *mem =
++        mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, base);
++    volatile uint32_t *emif = mem,temp;
++    
++   if (mem == MAP_FAILED){
++        return NULL;
++    }
++
++    emif[EMIF_PERF_CNT_CFG>>2] = EMIF_PERF_CFG2 << 16 | EMIF_PERF_CFG1;
++   
++    return mem;
++}
++
++static void emif_read(volatile uint32_t *emif, struct emif_stats *st)
++{
++    st->cycles = emif[EMIF_PERF_CNT_TIM>>2];
++    st->cnt1   = emif[EMIF_PERF_CNT_1>>2];
++    st->cnt2   = emif[EMIF_PERF_CNT_2>>2];
++}
++
++static void emif_print(const char *tag, struct emif_stats *st1,
++                       struct emif_stats *st2)
++{
++    uint32_t cycles = st2->cycles - st1->cycles;
++    uint32_t cnt1   = st2->cnt1   - st1->cnt1;
++    uint32_t cnt2   = st2->cnt2   - st1->cnt2;
++    printf("%s %s %2llu%% %s %2llu%%", tag,
++           emif_perf_tab[EMIF_PERF_CFG1].name, 100ull*cnt1/cycles,
++           emif_perf_tab[EMIF_PERF_CFG2].name, 100ull*cnt2/cycles);
++    fprintf(outfile,"%s%s= %2llu,%s%s= %2llu,", 
++           tag, emif_perf_tab[EMIF_PERF_CFG1].name, 100ull*cnt1/cycles,
++           tag, emif_perf_tab[EMIF_PERF_CFG2].name, 100ull*cnt2/cycles);
++}
++
++static int perf_init(void)
++{
++    int fd = open("/dev/mem", O_RDWR);
++    int err = 0;
++
++    if (fd == -1){
++       printf("error fd=open() \n");     
++       return -1;
++    }
++    emif1 = emif_init(fd, EMIF1_BASE);
++    emif2 = emif_init(fd, EMIF2_BASE);
++
++    if (!emif1 || !emif2){
++         printf("error if (!emif1 || !emif2) \n");       
++         err = -1;
++    }
++
++    close(fd);
++    return err;
++}
++
++static void perf_start(void)
++{
++    if (emif1) {
++        emif_read(emif1, &emif1_start);
++        emif_read(emif2, &emif2_start);
++    }
++}
++
++static void perf_stop(void)
++{
++    if (emif1) {
++        emif_read(emif1, &emif1_end);
++        emif_read(emif2, &emif2_end);
++    }
++}
++
++static void perf_print(void)
++{
++    if (emif1) {
++        emif_print("EMIF1", &emif1_start, &emif1_end);
++        printf("\t");
++        emif_print("EMIF2", &emif2_start, &emif2_end);
++        printf("\r");
++      fprintf(outfile, "\n");
++      fflush(outfile);
++      fflush(stdout);
++    }
++}
++
++static void perf_close(void)
++{
++    if (emif1) munmap(emif1, PAGE_SIZE);
++    if (emif2) munmap(emif2, PAGE_SIZE);
++}
++
++static int get_cfg(const char *name, int def)
++{
++    char *end;
++    int n = strtol(name, &end, 0);
++    int i;
++
++    if (!*end)
++        return n;
++
++    for (i = 0; i < sizeof(emif_perf_tab)/sizeof(emif_perf_tab[0]); i++)
++        if (!strcmp(name, emif_perf_tab[i].name))
++            return emif_perf_tab[i].code;
++
++    return def;
++}
++
++
++unsigned int emif_freq()
++{
++    volatile unsigned *tim1;
++    unsigned v1, v2;
++    int fd;
++    
++    /*calculation EMIF frequency 
++      EMIF_PERF_CNT_TIM = \n32-bit counter that 
++      continuously counts number for 
++      EMIF_FCLK clock cycles elapsed 
++      after EMIFis brought out of reset*/
++
++    fd = open("/dev/mem", O_RDONLY);
++    if (fd == -1) {
++        perror("/dev/mem");
++        return 1;
++    }
++
++    void *mem =
++    mem = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, EMIF1_BASE);
++    if (mem == MAP_FAILED) {
++        perror("mmap");
++        exit(1);
++    }
++
++    tim1 = (unsigned *)((char*)mem + EMIF_PERF_CNT_TIM);
++
++    v1 = *tim1;
++    gettimeofday(&t1, NULL);
++    sleep(2);
++    v2 = *tim1;
++    gettimeofday(&t2, NULL);
++    
++    munmap(mem, PAGE_SIZE);
++    close(fd);
++
++    return (v2 - v1) / tv_diff(&t1, &t2);
++
++}
++
++
++char config_file_path[100];
++char keylist[][50] = {
++      "DELAY",
++      "EMIF_PERF_CFG1",
++      "EMIF_PERF_CFG2",
++      "BANDWIDTH",
++      "STATCOLL",
++      "TOTAL_TIME",
++      "INTERVAL_US",
++      "INITIATORS",
++};
++
++char line[512], *p;
++char tokens[6][512];
++int temp, flag = 0;
++char *keyvalue, *pair;
++char key[100];
++int linecount=0;
++
++
++int debug=0;
++
++void print_valid_options(void)
++{
++   int i;
++        printf("Invalid key found\n");
++      printf("Supported keys are :\n");
++      for(i=0; i<sizeof(keylist)/sizeof(keylist[0]); i++)
++              printf("\t\t %s\n", keylist[i]);
++
++}
++int validatekey(char *ptr)
++{
++      int i;
++      for(i=0; i<sizeof(keylist)/sizeof(keylist[0]); i++)
++              if(strcmp(ptr, keylist[i]) == 0)
++                      return 0;
++
++      return 1;
++}
++
++void add_key_value(char *key, int value)
++{
++      printd("%s", "Inside add_key_value\n");
++      
++      if(strcmp(key, "BANDWIDTH") == 0) {
++              BANDWIDTH = value;
++              return;
++      }
++      if(strcmp(key, "STATCOLL") == 0) {
++              STATCOLL = value;
++              return;
++      }
++      else
++              printd("%s", "********** UNKNOWN**********");
++
++      if(BANDWIDTH == 1) {
++              if(strcmp(key, "DELAY") == 0)
++                      DELAY = value;
++              else if(strcmp(key, "EMIF_PERF_CFG1") == 0)
++                      EMIF_PERF_CFG1 = value;
++              else if(strcmp(key, "EMIF_PERF_CFG2") == 0)
++                      EMIF_PERF_CFG2 = value;
++      }
++      else
++              printf("NOTE: BANDWIDTH is not enabled, ignoring %s\n", key);
++
++
++        if(STATCOLL == 1) {
++              if(strcmp(key, "INTERVAL_US") == 0)
++                      INTERVAL_US = value;
++              else if(strcmp(key, "TOTAL_TIME") == 0)
++                      TOTAL_TIME = value;
++        }
++      else
++              printf("NOTE: STATCOLL is not enabled, ignoring %s\n", key);
++}
++
++void bandwidth_usage() {
++
++    printf("#########################################################\n##\n"
++
++           "##  usage    : ./Dra7xx_ddrstat   <DELAY>  <EMIF_PERF_CFG1>  <EMIF_PERF_CFG2> \n"
++           "##  default  :                    DELAY=1  EMIF_PERF_CFG1=9  EMIF_PERF_CFG2=10\n" 
++           "##  option   : for EMIF_PERF_CFG1 and EMIF_PERF_CFG2\n"
++           "##             0  -> access,\n"  
++           "##             1  -> activate,\n"
++           "##             2  -> read,\n"
++           "##             3  -> write,\n"
++           "##             4  -> fifo_cmd,\n"
++           "##             5  -> fifo_write,\n"
++           "##             6  -> fifo_read,\n"
++           "##             7  -> fifo_ret,\n"
++           "##             8  -> prio,\n"
++           "##             9  -> cmd_pend,\n"
++           "##             10 -> data    \n##\n"
++
++           "##  EMIF frq : %d MHz\n\n", emif_freq() );
++}
++
++
++int main(int argc, char **argv)
++{
++    int option;
++    FILE *fp;
++    int i;
++    int xpos = 600, ypos = 40;
++    
++    
++    /* Read config file */
++    /* Initialize this to turn off verbosity of getopt */
++    opterr = 0;
++
++//    while ((option = getopt (argc, argv, "df:")) != -1)
++    while ((option = getopt (argc, argv, "dx:y:")) != -1)
++    {
++          switch(option)
++          {
++#if 0
++                  case 'f':
++                          strcpy(config_file_path, optarg);
++                          break;
++#endif
++                  case 'd':
++                          debug=1;
++                          break;
++                  case 'x':
++                          xpos=atoi(optarg);
++                          break;
++                  case 'y':
++                          ypos=atoi(optarg);
++                          break;
++                  
++                  default:
++                          printf("Invalid option.. Exiting\n");
++                          exit(0);
++          }
++    }
++
++    printf("xpos = %d, ypos = %d\n", xpos, ypos);
++
++    strcpy(config_file_path,"config.ini");
++    fp = fopen(config_file_path, "r");
++    if (fp == NULL) {
++          fprintf(stderr, "couldn't open the specified file\n");
++          return -1;
++    }
++
++    while (fgets(line, sizeof line, fp)) {
++          printd("Line is = %s", line);
++
++          if (line[0] == '#' || line[0] == '\n') {
++                  continue;
++          }
++
++          memset(tokens, 0, sizeof(tokens));
++          i = 0;
++
++          pair = strtok (line," ,");
++          while (pair != NULL)
++          {
++                  printd ("\tPair is = %s\n",pair);
++                  strcpy(tokens[i++], pair);
++                  pair = strtok (NULL, " ,.-");
++          }
++
++          for(temp=0; temp< i; temp++)
++          {
++                  printd("Line %d: %s\n", temp, tokens[temp]);
++
++                  keyvalue = strtok (tokens[temp]," =");
++                  while (keyvalue != NULL)
++                  {
++                          if(flag == 0)
++                          {
++                                  if(validatekey(keyvalue))
++                                  {
++                                            print_valid_options();
++                                          exit(0);
++                                  }
++                                  strcpy(key, keyvalue);
++                                  printd ("\tKey is = %s\n",key);
++                                  flag++;
++                          }
++                          else
++                          {
++                                  printd ("\tValue is = %s",keyvalue);
++                                  printd (" (%d)\n", atoi(keyvalue));
++                                  add_key_value(key, atoi(keyvalue));
++                                  flag = 0;
++                          }
++                          keyvalue = strtok (NULL, " =");
++                  }
++          }
++
++
++
++          linecount++;
++          printd("%s", "------------------- \n");
++
++    }
++
++    fclose(fp);
++
++    printf("\n\nCOMPLETED: Parsing of the user specified parameters.. \n \
++                \nConfiguring device now.. \n\n");
++    if(BANDWIDTH == 1) {
++          bandwidth_usage();
++          if (DELAY <= 0)
++                  DELAY = 1;
++
++          if (perf_init()){
++                  printf("perf_init return non zero \n");
++                  return 1;
++          }
++
++          outfile = fopen("emif-performance.csv", "w+");
++          if (!outfile) {
++                  printf("\n Error opening file");
++          }
++          for (;;) {
++                  perf_start();
++                  sleep(DELAY);
++                  perf_stop();
++                  perf_print();
++          }
++
++          fclose(outfile);
++          perf_close();
++          return 0;
++    }
++
++    if(STATCOLL == 1) {
++          printf("STATISTICS COLLECTOR option chosen\n");
++            printf("------------------------------------------------\n\n");
++          fp = fopen("initiators.cfg", "r");
++          if (fp == NULL) {
++                  fprintf(stderr, "couldn't open the specified file initiators.cfg'\n");
++                  return -1;
++          }
++
++          int i=0;
++            char list[100][50];
++          memset(list, sizeof(list), 0);
++          while (fgets(line, sizeof line, fp)) {
++                  printf("Line is = %s", line);
++                  /* Slightly strange way to chop off the \n character */
++                  strtok(line, "\n");
++                  strcpy(list[i++], line);
++          }
++          fclose(fp);
++
++          statcoll_start(TOTAL_TIME, INTERVAL_US, list, xpos, ypos);
++    }
++
++}
++
+diff --git a/clients/soc_performance_monitor.c b/clients/soc_performance_monitor.c
+new file mode 100644
+index 0000000..5d1db32
+--- /dev/null
++++ b/clients/soc_performance_monitor.c
+@@ -0,0 +1,625 @@
++/*
++ * Copyright (C) 2016 Texas Instruments
++ * Author: Karthik Ramanan <karthik.ramanan@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <stdint.h>
++#include <signal.h>
++#include <time.h>
++#include <math.h>
++#include <unistd.h>
++#include <sys/time.h>
++#include <pthread.h>
++#include <errno.h>
++#include <unistd.h>
++#include <fcntl.h>
++#include <sys/stat.h>
++
++#include "time_bar_graph.h"
++
++#include "soc_performance_monitor.h"
++
++static int debug=0;
++
++static char readfifo[100]; 
++static int MAX_WIDTH=1920;
++static int MAX_HEIGHT=1080;
++static int x_pos=0;
++static int y_pos=40;
++
++void *ctx;
++struct time_graph_create_params tg_p;
++struct bar_graph_create_params bg_p;
++
++static int cpu_load_offset = 0;
++static int total_cpu_load_items = 0;
++static int total_elements = 0;
++
++struct _bar_graph_y_config *y_cfg;
++struct _text_config *t_cfg;
++char *tg_text[100]; 
++char *bg_text[100]; 
++
++
++int command_handler(int command, double *y, char **text)
++{
++      static int fd;
++      char buf[MAX_BUF];
++      int i, bytes, offset;
++
++      switch(command)
++      {
++              case OPEN:
++                      fd = open(readfifo, O_RDONLY|O_NONBLOCK);
++                      break;
++
++              case READ:
++
++                      /* open, read, and display the message from the FIFO */
++                      bytes=read(fd, buf, MAX_BUF);
++                       buf[bytes]='\0';
++                      if(bytes > 0) 
++                      {
++                              char command[100];
++                              char string[100];
++                              sscanf(buf, "%s %s", command, string);
++                              printd("Received %s\n", buf);
++                              if(strcmp(command, "TABLE:") == 0) 
++                              {
++                                      char field[100], value[100], unit[100];
++                                      sscanf(buf, "%s %s %s %s", command, field, value, unit);
++                                      for(i=0; i<cpu_load_offset; i++) {
++                                              if(strcmp(text[i*2], field) == 0) {
++                                                      printd("Updating value(%s), unit(%s)\n", value, unit);
++                                                      sprintf(text[i*2+1], "%s %s", value, unit);
++                                              }
++                                      }
++                              }
++                              else if(strcmp(command, "CPULOAD:") == 0) 
++                              {
++                                      char field[100], value[100];
++
++                                      sscanf(buf, "%s %s %s", command, field, value);
++
++                                      for(i=cpu_load_offset; i<cpu_load_offset+total_cpu_load_items; i++) {
++                                              if(strcmp(text[i*2], field) == 0) {
++                                                      y[i*2+1] = atoi(value)/100.0;
++                                                      sprintf(text[i*2+1], " %02s%s", value,"%");
++                                                      printd("CPULOAD: Updating %s with %s\n", field, value);
++                                              }
++                                      }
++                              }
++                              else if(strcmp(command, "MOVE:") == 0) 
++                              {
++                                      char value[100];
++                                      printd("Received MOVE command : %s\n", buf);
++                                      sscanf(string, "%s", value);
++                                      sprintf(tg_p.title, "CPU Usage[@position-req=%sx%d]", value, y_pos);
++                                      move_graph(ctx, &tg_p);
++                              }
++                              else
++                              {
++                                      printf("ERROR: Received unexpected data from FIFO - \" %s \" \n", buf);
++                              }
++                              memset(buf, 0x0, sizeof(buf));
++                      }
++
++                      break;
++
++              case CLOSE:
++                      close(fd);
++                      break;
++      }
++      return bytes;
++}
++
++volatile sig_atomic_t sigtermed = 0;
++
++void my_signal_handler(int signum)
++{
++      if (signum == SIGTERM || signum == SIGINT) {
++              sigtermed = 1;
++      }
++}
++
++int get_strings_in_section(char *string, char **output)
++{
++      FILE *fd;
++      char line[512];
++      int total_strings = 0;
++      
++      fd = fopen("soc_performance_monitor.cfg", "r");
++      if(fd == NULL) {
++              fprintf(stderr, "ERROR: Unable to open file soc_performance_monitor.cfg\n");
++              fprintf(stderr, "       Please copy the file from /etc/visualization_scripts into current directory\n");
++              exit(0);
++      }
++      
++      while(fgets(line, sizeof line, fd)) {
++          if(strstr(line, string)) {
++              printf("\n-------------------------------------------------\n");
++              printf("CONFIG FILE PARSE: Found section %s in line : %s\n", string, line);
++              break;
++          }
++      }
++
++      while(fgets(line, sizeof line, fd)) {
++          printd("Line is = %s", line);
++
++          if (line[0] == '#' || line[0] == '\n' || line[0] == '[') {
++                  break;
++          }
++
++          line[strlen(line) - 1] = '\0';
++          strcpy(output[total_strings++], line);
++          
++      }
++      fclose(fd);
++
++      return total_strings;
++}
++
++
++void fill_cpu_load_details(int start_offset, int end_offset, char **output, struct table_configuration *table_config)
++{
++      int i;
++
++      const int BL_START_X = table_config->BL_START_X;
++      const int BL_START_Y = table_config->BL_START_Y;
++      const int BAR_GAP = table_config->BAR_GAP;
++      const int BAR_HEIGHT = table_config->BAR_HEIGHT;
++      const int BAR_WIDTH = table_config->BAR_WIDTH;
++      const int TR_START_X = table_config->TR_START_X;
++      const int TR_START_Y = table_config->TR_START_Y;
++      const int FONT_SIZE = table_config->FONT_SIZE;
++      printf("Filling from %d to %d\n", start_offset, end_offset);
++      cpu_load_offset = start_offset;
++
++      for(i=start_offset; i< end_offset-1; i++) {
++              y_cfg[i*2].region.bottom_left.x = BL_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH);
++              y_cfg[i*2].region.bottom_left.y = BL_START_Y;
++              y_cfg[i*2].region.top_right.x = TR_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH);
++              y_cfg[i*2].region.top_right.y = TR_START_Y;
++              y_cfg[i*2].line_color.r = 1.0;
++              y_cfg[i*2].line_color.g = 1.0;
++              y_cfg[i*2].line_color.b = 1.0;
++              y_cfg[i*2].line_color.a = 1.0;
++              y_cfg[i*2].fill_color.r = 0.0;
++              y_cfg[i*2].fill_color.g = 0.0;
++              y_cfg[i*2].fill_color.b = 1.0;
++              y_cfg[i*2].fill_color.a = 0.7;
++
++              y_cfg[i*2+1].region.bottom_left.x = BL_START_X +(i-start_offset) * (BAR_GAP + BAR_WIDTH);
++              y_cfg[i*2+1].region.bottom_left.y = BL_START_Y;
++              y_cfg[i*2+1].region.top_right.x = TR_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH);
++              y_cfg[i*2+1].region.top_right.y = TR_START_Y;
++              y_cfg[i*2+1].line_color.r = 1.0;
++              y_cfg[i*2+1].line_color.g = 1.0;
++              y_cfg[i*2+1].line_color.b = 1.0;
++              y_cfg[i*2+1].line_color.a = 1.0;
++              y_cfg[i*2+1].fill_color.r = 1.0;
++              y_cfg[i*2+1].fill_color.g = 0.0;
++              y_cfg[i*2+1].fill_color.b = 0.0;
++              y_cfg[i*2+1].fill_color.a = 1.0;
++
++      
++              t_cfg[i*2].color.r = 1.0;
++              t_cfg[i*2].color.g = 1.0;
++              t_cfg[i*2].color.b = 1.0;
++              t_cfg[i*2].color.a = 1.0;
++              t_cfg[i*2].at.x = BL_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH);
++              t_cfg[i*2].at.y = BL_START_Y + FONT_SIZE;
++              t_cfg[i*2].fontsize = FONT_SIZE;
++
++              t_cfg[i*2+1].color.r = 1.0;
++              t_cfg[i*2+1].color.g = 1.0;
++              t_cfg[i*2+1].color.b = 1.0;
++              t_cfg[i*2+1].color.a = 1.0;
++              t_cfg[i*2+1].at.x = BL_START_X + (i-start_offset) * (BAR_GAP + BAR_WIDTH);
++              t_cfg[i*2+1].at.y = BL_START_Y - BAR_HEIGHT -  FONT_SIZE;
++              t_cfg[i*2+1].fontsize = FONT_SIZE;
++
++              strcpy(bg_text[i*2], output[i - start_offset]);
++              strcpy(bg_text[i*2+1], "0%");
++      }
++
++      t_cfg[(end_offset-1)*2].color.r = 0.0;
++      t_cfg[(end_offset-1)*2].color.g = 1.0;
++      t_cfg[(end_offset-1)*2].color.b = 1.0;
++      t_cfg[(end_offset-1)*2].color.a = 1.0;
++      t_cfg[(end_offset-1)*2].at.x = BL_START_X + 80;
++      t_cfg[(end_offset-1)*2].at.y = TR_START_Y - 40;
++      t_cfg[(end_offset-1)*2].fontsize = FONT_SIZE + 3;
++
++      printd("Copying title string %s\n", output[end_offset - start_offset -1]);
++      strcpy(bg_text[(end_offset-1)*2], output[end_offset - start_offset-1]);
++}
++
++void fill_table_details(int start_offset, int end_offset, char **output, struct table_configuration *table_config)
++{
++      int i;
++
++      const int BL_START_X = table_config->BL_START_X;
++      const int BL_START_Y = table_config->BL_START_Y;
++      const int BAR_GAP = table_config->BAR_GAP;
++      const int BAR_HEIGHT = table_config->BAR_HEIGHT;
++      const int BAR_WIDTH = table_config->BAR_WIDTH;
++      const int TR_START_X = table_config->TR_START_X;
++      const int TR_START_Y = table_config->TR_START_Y;
++      const int FONT_SIZE = table_config->FONT_SIZE;
++      printf("Filling from %d to %d\n", start_offset, end_offset);
++
++       
++        char tokenize[200];
++      char tokens[10][100];
++      char *pair, *key, *value;
++      int k=0;
++      char title[100], unit[100];
++
++      strcpy(tokenize, output[end_offset - start_offset - 1]);
++      memset(tokens, 0, sizeof(tokens));
++
++      k=0;
++      pair = strtok (tokenize,",");
++      while (pair != NULL) {
++              strcpy(tokens[k++], pair);
++              pair = strtok (NULL, ",");
++      }
++
++      i=0;
++      memset(title, 0, sizeof(title));
++      memset(unit, 0, sizeof(unit));
++      while(i < k) {
++              key=strtok(tokens[i], "=");
++              if(key != NULL) {
++                      if(strcmp(key,"TITLE") == 0) {
++                              value = strtok(NULL, "=");
++                              if(value != NULL) {
++                                      strcpy(title, value);
++                              }
++                      }
++                      if(strcmp(key,"UNIT") == 0) {
++                              value = strtok(NULL, "=");
++                              if(value != NULL) {
++                                      strcpy(unit, value);
++                              }
++                      }
++              }
++              i++;
++      }
++
++      for(i=start_offset; i< end_offset-1; i++) {
++              y_cfg[i*2].region.bottom_left.x = BL_START_X;
++              y_cfg[i*2].region.bottom_left.y = BL_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT);
++              y_cfg[i*2].region.top_right.x = TR_START_X; 
++              y_cfg[i*2].region.top_right.y = TR_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT);
++              y_cfg[i*2].line_color.r = 1.0;
++              y_cfg[i*2].line_color.g = 1.0;
++              y_cfg[i*2].line_color.b = 1.0;
++              y_cfg[i*2].line_color.a = 1.0;
++              y_cfg[i*2].fill_color.r = 0.0;
++              y_cfg[i*2].fill_color.g = 0.3;
++              y_cfg[i*2].fill_color.b = 0.0;
++              y_cfg[i*2].fill_color.a = 0.7;
++
++              y_cfg[i*2+1].region.bottom_left.x = TR_START_X;
++              y_cfg[i*2+1].region.bottom_left.y = BL_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT);
++              y_cfg[i*2+1].region.top_right.x = TR_START_X + (BAR_WIDTH); //+ 1 * BL_START_X;
++              y_cfg[i*2+1].region.top_right.y = TR_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT);;
++              y_cfg[i*2+1].line_color.r = 1.0;
++              y_cfg[i*2+1].line_color.g = 1.0;
++              y_cfg[i*2+1].line_color.b = 1.0;
++              y_cfg[i*2+1].line_color.a = 1.0;
++              y_cfg[i*2+1].fill_color.r = 0.3;
++              y_cfg[i*2+1].fill_color.g = 0.0;
++              y_cfg[i*2+1].fill_color.b = 0.0;
++              y_cfg[i*2+1].fill_color.a = 0.7;
++
++      
++              t_cfg[i*2].color.r = 1.0;
++              t_cfg[i*2].color.g = 1.0;
++              t_cfg[i*2].color.b = 1.0;
++              t_cfg[i*2].color.a = 1.0;
++              t_cfg[i*2].at.x = BL_START_X + 5;
++              t_cfg[i*2].at.y = BL_START_Y + (i - start_offset) * (BAR_GAP+BAR_HEIGHT) -5;
++              t_cfg[i*2].fontsize = FONT_SIZE;
++
++              t_cfg[i*2+1].color.r = 1.0;
++              t_cfg[i*2+1].color.g = 1.0;
++              t_cfg[i*2+1].color.b = 1.0;
++              t_cfg[i*2+1].color.a = 1.0;
++              t_cfg[i*2+1].at.x = TR_START_X + 50;//BAR_WIDTH + TR_START_X;
++              t_cfg[i*2+1].at.y = BL_START_Y + (i - start_offset) * (BAR_GAP + BAR_HEIGHT) -5;
++              t_cfg[i*2+1].fontsize = FONT_SIZE;
++
++              printd("Copying string %s at %d\n", output[i-start_offset], i);
++              strcpy(bg_text[i*2], output[i-start_offset]);
++              printd("Setting text 0  %s at %d\n", unit, i*2+1);
++              sprintf(bg_text[i*2+1], "0 %s", unit);
++      }
++      for(i=start_offset; i< end_offset*2; i++) {
++              printd("%d - (%d, %d) to (%d, %d)\n", i, y_cfg[i].region.bottom_left.x,  y_cfg[i].region.bottom_left.y,  y_cfg[i].region.top_right.x,  y_cfg[i].region.top_right.y);
++      }
++
++      t_cfg[(end_offset-1)*2].color.r = 0.0;
++      t_cfg[(end_offset-1)*2].color.g = 1.0;
++      t_cfg[(end_offset-1)*2].color.b = 1.0;
++      t_cfg[(end_offset-1)*2].color.a = 1.0;
++      t_cfg[(end_offset-1)*2].at.x = BL_START_X + 80;
++      t_cfg[(end_offset-1)*2].at.y = BL_START_Y - 40;
++      t_cfg[(end_offset-1)*2].fontsize = FONT_SIZE + 3;
++
++      printd("Copying title string %s\n", title);
++      strcpy(bg_text[(end_offset-1)*2], title);
++
++}
++      
++
++int get_key_value_from_string(char *string, char *limiter, char *key, char *value)
++{
++      char *mykey, *myvalue;
++
++      mykey=strtok(string, limiter);
++      if(mykey != NULL) {
++              myvalue = strtok(NULL, "=");
++              strtok(myvalue, "\n");
++              if(myvalue == NULL) {
++                      return -1;
++              }
++      }
++      else {
++              return -1;
++      }
++      printd("Key is %s\n", mykey);
++      printd("Value is %s\n", myvalue);
++      strcpy(key, mykey);
++      strcpy(value, myvalue);
++      return 0;
++
++}
++
++void populate_table_configuration(struct table_configuration *tbl_cfg, int cur_items, char **item_list)
++{
++      static int total_items = 0;
++      static int total_tables = 0;
++      
++      tbl_cfg->BAR_HEIGHT = 25;
++      tbl_cfg->BAR_WIDTH = 150;
++      tbl_cfg->BL_START_X = 40;
++      tbl_cfg->BL_START_Y = 80 + (total_items + total_tables) * tbl_cfg->BAR_HEIGHT;
++      tbl_cfg->BAR_GAP = 0;
++      tbl_cfg->TR_START_X = tbl_cfg->BL_START_X + tbl_cfg->BAR_WIDTH;
++      tbl_cfg->TR_START_Y = tbl_cfg->BL_START_Y - tbl_cfg->BAR_HEIGHT;
++      tbl_cfg->FONT_SIZE = 15;
++
++      printf("Proceeding with filling out details...\n");
++      if(cur_items > 0)
++              fill_table_details(total_items, total_items+cur_items, item_list, tbl_cfg);
++
++      total_items += cur_items;
++      if(cur_items > 0)
++              total_tables++;
++
++      printf("total_items = %d, total_tables = %d\n", total_items, total_tables);
++      return;
++}
++
++int fill_list_from_section(char **section_list, char *section_name)
++{
++      int total_items, j;
++
++      for(j=0; j<20; j++) {
++              section_list[j] = malloc(100);
++      }
++
++      total_items = get_strings_in_section(section_name, section_list);
++      printf("\tThe total values in the section %s are %d\n", section_name, total_items);
++      for(j=0; j<total_items; j++) {
++              printf("\t\tThe returned strings for BOOT_TIME are %s\n", section_list[j]);
++      }
++
++      total_elements += total_items;
++
++      return total_items;
++}
++
++int main(int argc, char *argv[])
++{
++      double *bg_y;
++      double *tg_y;
++      int i,j;
++      int refresh_rate;
++
++      if (SIG_ERR == signal(SIGPIPE,SIG_IGN))
++              exit(1);
++
++      if (SIG_ERR == signal(SIGINT,my_signal_handler))
++              exit(1);
++
++      if (SIG_ERR == signal(SIGTERM,my_signal_handler))
++              exit(1);
++
++      if(argc == 2) {
++              printf("Enabling debug\n");
++              debug = atoi(argv[1]);
++      }
++      else {
++              printf("Debug is disabled\n");
++              debug = 0;
++      }
++
++      char *output[20];
++      int total = fill_list_from_section(output, "GLOBAL");
++      for(j=0; j<total; j++) {
++              char key[100], value[100];
++              int ret = get_key_value_from_string(output[j], "=", key, value);
++              if(ret == 0) {
++                      if(strcmp(key, "FIFO") == 0) {
++                              strcpy(readfifo, value);
++                      }
++                      if(strcmp(key, "REFRESH_RATE_USEC") == 0) {
++                              refresh_rate = atoi(value);
++                      }
++                      if(strcmp(key, "MAX_WIDTH") == 0) {
++                              MAX_WIDTH = atoi(value);
++                      }
++                      if(strcmp(key, "MAX_HEIGHT") == 0) {
++                              MAX_HEIGHT = atoi(value);
++                      }
++                      if(strcmp(key, "X_POS") == 0) {
++                              x_pos = atoi(value);
++                      }
++                      if(strcmp(key, "Y_POS") == 0) {
++                              y_pos = atoi(value);
++                      }
++              }
++                              
++      }
++
++      printf("\n-------------------------------------------------\n");
++      printf("Configured REFRESH_RATE is %d\n", refresh_rate);
++      printf("Configured FIFO is %s\n", readfifo);
++      printf("Configured MAX_WIDTH is %d\n", MAX_WIDTH);
++      printf("Configured MAX_HEIGHT is %d\n", MAX_HEIGHT);
++      printf("Configured starting location is (%d, %d)\n", x_pos, y_pos);
++      printf("\n-------------------------------------------------\n");
++
++      int fd = open(readfifo, O_RDONLY|O_NONBLOCK);
++      if (fd != -1) {
++              printf("SUCCESS: Configured FIFO exists\n");
++              close(fd);
++      }
++      else {
++              printf("ERROR: %s not found\nPlease create the fifo by executing mkfifo %s before running the application\n", readfifo, readfifo);
++              exit(0);
++      }
++              
++
++      bg_p.title = malloc(100);
++      sprintf(bg_p.title, "CPU Usage[@position-req=%dx%d]", x_pos, y_pos);
++
++      /* ------------------------------------------------------------------------*/
++      /* Section for populating all lists from cfg sections*/
++      /* ------------------------------------------------------------------------*/
++      char *boot_list[20];
++      int total_boot_items = fill_list_from_section(boot_list, "BOOT_TIME");
++
++      char *temperature_list[20];
++      int total_temperature_items = fill_list_from_section(temperature_list, "TEMPERATURE");
++
++      char *cpu_load_list[20];
++      total_cpu_load_items = fill_list_from_section(cpu_load_list, "CPU_LOAD");
++
++      char *voltage_list[20];
++      int total_voltage_items = fill_list_from_section(voltage_list, "VOLTAGE");
++
++      char *frequency_list[20];
++      int total_frequency_items = fill_list_from_section(frequency_list, "FREQUENCY");
++      /* ------------------------------------------------------------------------*/
++      /* total_elements will be updated inside the fill_list_from_section function */
++
++      t_cfg = malloc(sizeof(struct _text_config) * (total_elements*2 + 1));
++      y_cfg = malloc(sizeof(struct _bar_graph_y_config) * total_elements*2);
++      bg_p.num_of_y_items = total_elements*2;
++      bg_p.y_config_array = y_cfg;
++      bg_p.num_of_text_items = total_elements*2 + 1;
++      bg_p.text_config_array = t_cfg;
++
++      bg_y = malloc(sizeof(double) * total_elements * 2);
++      for(i=0; i< (total_elements*2+1); i++) {
++              bg_text[i] = malloc(150);
++              bg_y[i] = 1.0;
++      }
++
++      tg_y = malloc(sizeof(double) * total_elements * 2);
++      for(i=0; i< (total_elements*2+1); i++) {
++              tg_text[i] = malloc(150);
++              tg_y[i] = 0.1 * i;
++      }
++
++      struct table_configuration boot_table_config; 
++        populate_table_configuration(&boot_table_config, total_boot_items, boot_list);
++
++      struct table_configuration temp_table_config; 
++        populate_table_configuration(&temp_table_config, total_temperature_items, temperature_list);
++
++      struct table_configuration voltage_table_config; 
++        populate_table_configuration(&voltage_table_config, total_voltage_items, voltage_list);
++
++      struct table_configuration frequency_table_config; 
++        populate_table_configuration(&frequency_table_config, total_frequency_items, frequency_list);
++
++      struct table_configuration cpu_load_config; 
++      cpu_load_config.BL_START_X = 40;
++      cpu_load_config.BL_START_Y = 80 + (total_boot_items + total_temperature_items + total_voltage_items + total_frequency_items+ 4) * boot_table_config.BAR_HEIGHT + 80 /*cpu_load_config.BAR_HEIGHT */;
++      cpu_load_config.BAR_GAP = 20;
++      cpu_load_config.BAR_HEIGHT = 80;
++      cpu_load_config.BAR_WIDTH = 40;
++      cpu_load_config.TR_START_X = cpu_load_config.BL_START_X + cpu_load_config.BAR_WIDTH;
++      cpu_load_config.TR_START_Y = cpu_load_config.BL_START_Y - cpu_load_config.BAR_HEIGHT;
++      cpu_load_config.FONT_SIZE = 15;
++      if(total_cpu_load_items > 0) {
++              fill_cpu_load_details(total_boot_items+total_temperature_items+total_voltage_items+total_frequency_items, total_boot_items+total_temperature_items+total_voltage_items+total_frequency_items+total_cpu_load_items, cpu_load_list, &cpu_load_config);
++      }
++      else {
++              cpu_load_offset = total_boot_items + total_temperature_items + total_voltage_items + total_frequency_items;
++      }
++
++      tg_p.title=(char *)malloc(100);
++      sprintf(tg_p.title, "CPU Usage[@position-req=%dx%d]", x_pos, y_pos);
++      tg_p.height = MAX_HEIGHT;
++      tg_p.width = MAX_WIDTH;
++
++      struct _y_config *tg_y_cfg = malloc(tg_p.num_of_y_items * sizeof(struct _y_config));
++      tg_p.y_config_array = tg_y_cfg;
++      tg_p.text_config_array = t_cfg;
++
++        printf("Proceeding to create starting visualization...\n");
++      ctx = time_graph_create(argc, argv, &tg_p);
++      if (!ctx) {
++              printf("Unable to create time_graph... \n");
++              exit(0);
++      }
++
++      ctx = bar_graph_create(argc, argv, &bg_p);
++      if (!ctx) {
++              printf("Error creating context\n");
++              exit(0);
++      }
++
++      command_handler(OPEN, NULL, NULL);
++
++      /* Plot the graph first time */
++      time_graph_plot(ctx, tg_y, (const char **)tg_text);
++      bar_graph_plot(ctx, bg_y, (const char **)bg_text);
++
++      while (!sigtermed)
++      {
++              usleep(refresh_rate);
++              int bytes_read = command_handler(READ, bg_y, bg_text);
++              if(bytes_read > 0) {
++                      time_graph_plot(ctx, tg_y, (const char **)tg_text);
++                      bar_graph_plot(ctx, bg_y, (const char **)bg_text);
++              }
++      }
++
++      bar_graph_destroy(ctx);
++      command_handler(CLOSE, NULL, NULL);
++      return 0;
++}
+diff --git a/clients/soc_performance_monitor.h b/clients/soc_performance_monitor.h
+new file mode 100644
+index 0000000..861c8c7
+--- /dev/null
++++ b/clients/soc_performance_monitor.h
+@@ -0,0 +1,40 @@
++#define __SLEEP  usleep(1000000)
++
++#define MAX_BUF 1024
++#define OPEN 1
++#define READ 2
++#define CLOSE 3
++
++#define MAX_COLORS 12
++
++#define printd(fmt, ...) \
++      do { if (debug) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
++
++
++struct _rgba pallette[MAX_COLORS] = 
++{
++      { 1.0, 0.0, 0.0, 1.0 },
++      { 0.0, 0.5, 0.0, 1.0 },
++      { 0.0, 0.0, 1.0, 1.0 },
++      { 0.0, 0.0, 0.0, 1.0 },
++      { 0.0, 0.5, 1.0, 1.0 },
++      { 1.0, 0.0, 1.0, 1.0 },
++      { 0.5, 0.5, 1.0, 1.0 },
++      { 1.0, 0.5, 0.0, 1.0 },
++      { 0.5, 0.5, 0.25, 1.0 },
++      { 0.5, 0.0, 0.0, 1.0 },
++      { 1.0, 0.5, 0.5, 1.0 },
++      { 0.0, 0.0, 0.20, 1.0 }
++};
++
++struct table_configuration {
++      int BL_START_X;
++      int BL_START_Y;
++      int BAR_GAP;
++      int BAR_HEIGHT;
++      int BAR_WIDTH;
++      int TR_START_X;
++      int TR_START_Y;
++      int FONT_SIZE;
++};
++
+diff --git a/clients/statcoll.c b/clients/statcoll.c
+new file mode 100644
+index 0000000..5d5cae7
+--- /dev/null
++++ b/clients/statcoll.c
+@@ -0,0 +1,1433 @@
++/*
++ * Copyright (C) 2015 Texas Instruments
++ * created by prash@ti.com on 16 Jan 2013
++ * Adapted to Linux with changes in framework: Karthik R <karthik.ramanan@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program.  If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/mman.h>
++#include <fcntl.h>
++#include <signal.h>
++#include <unistd.h>
++#include <sys/time.h>
++
++#include "statcoll.h"
++#include "statcoll_gui.h"
++#include "time_bar_graph.h"
++
++#define ENABLE_MODE      0x0
++#define READ_STATUS_MODE 0x1
++
++
++
++#define OPEN 1
++#define READ 2
++#define CLOSE 3
++
++
++#if 1
++#define __SLEEP  sleep(1)
++#else
++#define __SLEEP  usleep(100000)
++#endif
++//#define DUMMY_MODE
++
++#define MAX_COLORS 12
++
++struct _rgba pallette[MAX_COLORS] = 
++{
++      { 1.0, 0.0, 0.0, 1.0 },
++      { 0.0, 0.5, 0.0, 1.0 },
++      { 0.0, 0.0, 1.0, 1.0 },
++      { 0.0, 0.0, 0.0, 1.0 },
++      { 0.0, 0.5, 1.0, 1.0 },
++      { 1.0, 0.0, 1.0, 1.0 },
++      { 0.5, 0.5, 1.0, 1.0 },
++      { 1.0, 0.5, 0.0, 1.0 },
++      { 0.5, 0.5, 0.25, 1.0 },
++      { 0.5, 0.0, 0.0, 1.0 },
++      { 1.0, 0.5, 0.5, 1.0 },
++      { 0.0, 0.0, 0.20, 1.0 }
++};
++
++const struct list_of_initiators initiators[STATCOL_MAX] =
++{
++    { STATCOL_EMIF1_SYS, "STATCOL_EMIF1_SYS" },
++    { STATCOL_EMIF2_SYS,"STATCOL_EMIF2_SYS" },
++    { STATCOL_MA_MPU_P1,"STATCOL_MPU_P1" },
++    { STATCOL_MA_MPU_P2,"STATCOL_MPU_P2" },
++    { STATCOL_MPU1,"STATCOL_MPU1" },
++    { STATCOL_MMU1,"STATCOL_MMU1" },
++    { STATCOL_TPTC_RD1,"STATCOL_TPTC_RD1" },
++    { STATCOL_TPTC_WR1,"STATCOL_TPTC_WR1" },
++    { STATCOL_TPTC_RD2,"STATCOL_TPTC_RD2" },
++    { STATCOL_TPTC_WR2,"STATCOL_TPTC_WR2" },
++    { STATCOL_VIP1_P1,"STATCOL_VIP1_P1" },
++    { STATCOL_VIP1_P2,"STATCOL_VIP1_P2" },
++    { STATCOL_VIP2_P1,"STATCOL_VIP2_P1" },
++    { STATCOL_VIP2_P2,"STATCOL_VIP2_P2" },
++    { STATCOL_VIP3_P1,"STATCOL_VIP3_P1" },
++    { STATCOL_VIP3_P2,"STATCOL_VIP3_P2" },
++    { STATCOL_VPE_P1,"STATCOL_VPE_P1" },
++    { STATCOL_VPE_P2,"STATCOL_VPE_P2" },
++    { STATCOL_EVE1_TC0,"STATCOL_EVE1_TC0" },
++    { STATCOL_EVE1_TC1,"STATCOL_EVE1_TC1" },
++    { STATCOL_EVE2_TC0,"STATCOL_EVE2_TC0" },
++    { STATCOL_EVE2_TC1,"STATCOL_EVE2_TC1" },
++    { STATCOL_EVE3_TC0,"STATCOL_EVE3_TC0" },
++    { STATCOL_EVE3_TC1,"STATCOL_EVE3_TC1" },
++    { STATCOL_EVE4_TC0,"STATCOL_EVE4_TC0" },
++    { STATCOL_EVE4_TC1,"STATCOL_EVE4_TC1" },
++    { STATCOL_DSP1_MDMA,"STATCOL_DSP1_MDMA" },
++    { STATCOL_DSP1_EDMA,"STATCOL_DSP1_EDMA" },
++    { STATCOL_DSP2_MDMA,"STATCOL_DSP2_MDMA" },
++    { STATCOL_DSP2_EDMA,"STATCOL_DSP2_EDMA" },
++    { STATCOL_IVA,"STATCOL_IVA" },
++    { STATCOL_GPU_P1,"STATCOL_GPU_P1" },
++    { STATCOL_GPU_P2,"STATCOL_GPU_P2" },
++    { STATCOL_BB2D_P1,"STATCOL_BB2D_P1" },
++    { STATCOL_DSS,"STATCOL_DSS" },
++    { STATCOL_CSI2_2,"STATCOL_CSI2_2" },
++    { STATCOL_MMU2,"STATCOL_MMU2" },
++    { STATCOL_IPU1,"STATCOL_IPU1" },
++    { STATCOL_IPU2,"STATCOL_IPU2" },
++    { STATCOL_DMA_SYSTEM_RD,"STATCOL_DMA_SYSTEM_RD" },
++    { STATCOL_DMA_SYSTEM_WR,"STATCOL_DMA_SYSTEM_WR" },
++    { STATCOL_CSI2_1,"STATCOL_CSI2_1" },
++    { STATCOL_USB3_SS,"STATCOL_USB3_SS" },
++    { STATCOL_USB2_SS,"STATCOL_USB2_SS" },
++    { STATCOL_USB2_ULPI_SS1,"STATCOL_USB2_ULPI_SS1" },
++    { STATCOL_USB2_ULPI_SS2,"STATCOL_USB2_ULPI_SS2" },
++    { STATCOL_PCIE_SS1,"STATCOL_PCIE_SS1" },
++    { STATCOL_PCIE_SS2,"STATCOL_PCIE_SS2" },
++    { STATCOL_DSP1_CFG,"STATCOL_DSP1_CFG" },
++    { STATCOL_DSP2_CFG,"STATCOL_DSP2_CFG" },
++    { STATCOL_GMAC_SW,"STATCOL_GMAC_SW" },
++    { STATCOL_PRUSS1_P1,"STATCOL_PRUSS1_P1" },
++    { STATCOL_PRUSS1_P2,"STATCOL_PRUSS1_P2" },
++    { STATCOL_PRUSS2_P1,"STATCOL_PRUSS2_P1" },
++    { STATCOL_PRUSS2_P2,"STATCOL_PRUSS2_P2" },
++    { STATCOL_DMA_CRYPTO_RD,"STATCOL_DMA_CRYPTO_RD" },
++    { STATCOL_DMA_CRYPTO_WR,"STATCOL_DMA_CRYPTO_WR" },
++    { STATCOL_MPU2,"STATCOL_MPU2" },
++    { STATCOL_MMC1,"STATCOL_MMC1" },
++    { STATCOL_MMC2,"STATCOL_MMC2" },
++    { STATCOL_SATA,"STATCOL_SATA" },
++    { STATCOL_MLBSS,"STATCOL_MLBSS" },
++    { STATCOL_BB2D_P2,"STATCOL_BB2D_P2" },
++    { STATCOL_IEEE1500,"STATCOL_IEEE1500" },
++    { STATCOL_DBG,"STATCOL_DBG" },
++    { STATCOL_VCP1,"STATCOL_VCP1" },
++    { STATCOL_OCMC_RAM1,"STATCOL_OCMC_RAM1" },
++    { STATCOL_OCMC_RAM2,"STATCOL_OCMC_RAM2" },
++    { STATCOL_OCMC_RAM3,"STATCOL_OCMC_RAM3" },
++    { STATCOL_GPMC,"STATCOL_GPMC" },
++    { STATCOL_MCASP1,"STATCOL_MCASP1" },
++    { STATCOL_MCASP2,"STATCOL_MCASP2" },
++    { STATCOL_MCASP3,"STATCOL_MCASP3" },
++    { STATCOL_VCP2,  "STATCOL_VCP2" }
++}; 
++
++StatCollectorObj gStatColState;
++
++static void *statcoll_base_mem;
++static int *l3_3_clkctrl;
++
++static UInt32 *statCountDSS = NULL;
++static UInt32 *statCountIVA = NULL;
++static UInt32 *statCountBB2DP1 = NULL;
++static UInt32 *statCountBB2DP2 = NULL;
++static UInt32 *statCountUSB4 = NULL;
++static UInt32 *statCountSata = NULL;
++static UInt32 *statCountEmif1 = NULL;
++static UInt32 *statCountEmif2 = NULL;
++
++
++static statcoll_initiators_object global_object[STATCOL_MAX];
++UInt32 statCountIdx = 0;
++UInt32 TRACE_SZ = 0;
++
++void create_overall_box(struct _bar_graph_y_config *y_cfg, struct _text_config *t_cfg, char *text[])
++{
++        int i=0;
++
++        memset(y_cfg, 0x0, sizeof(struct _y_config)*25);
++        memset(t_cfg, 0x0, sizeof(struct _text_config)*25);
++
++
++        for(i=0; i<TOTAL_Y_PARAMETERS; i++) {
++                (y_cfg+i)->line_color.r = 1.0;
++                (y_cfg+i)->line_color.g = 1.0;
++                (y_cfg+i)->line_color.b = 1.0;
++                (y_cfg+i)->line_color.a = 0.7;
++                (y_cfg+i)->fill_color.r = 0.0;
++                (y_cfg+i)->fill_color.g = 0.0;
++                (y_cfg+i)->fill_color.b = 0.0;
++                (y_cfg+i)->fill_color.a = 0.1;
++        }
++
++        (y_cfg+0)->region.bottom_left.x = 0;
++        (y_cfg+0)->region.bottom_left.y = MAX_HEIGHT - HEIGHT_EMIF_AREA;
++        (y_cfg+0)->region.top_right.x = MAX_WIDTH;
++        (y_cfg+0)->region.top_right.y = 0;
++
++        (t_cfg+0)->at.x = MAX_WIDTH/2 - 8*FONT_SIZE - 50;
++        (t_cfg+0)->at.y = BORDER - FONT_SIZE + 6;
++        strcpy(text[0], string_list[0]);
++
++        (y_cfg+1)->region.bottom_left.x = TIME_GRAPH_AREA_BL_X;
++        (y_cfg+1)->region.bottom_left.y = TIME_GRAPH_AREA_BL_Y;
++        (y_cfg+1)->region.top_right.x = TIME_GRAPH_AREA_TR_X;
++        (y_cfg+1)->region.top_right.y = TIME_GRAPH_AREA_TR_Y;
++
++        (t_cfg+1)->at.x = TIME_GRAPH_AREA_BL_X - 2*FONT_SIZE;
++        (t_cfg+1)->at.y = TIME_GRAPH_AREA_TR_Y;
++        strcpy(text[1],string_list[1]);
++
++        for(i=2; i<7; i++)
++        {
++                (y_cfg+i)->region.bottom_left.x = TIME_GRAPH_AREA_BL_X;
++                (y_cfg+i)->region.bottom_left.y = TIME_GRAPH_AREA_BL_Y;// - (i-2) * (30);
++                (y_cfg+i)->region.top_right.x = TIME_GRAPH_AREA_TR_X;
++                (y_cfg+i)->region.top_right.y = TIME_GRAPH_AREA_TR_Y + (i-1) * ((TIME_GRAPH_AREA_BL_Y - TIME_GRAPH_AREA_TR_Y)/5);
++                (t_cfg+i)->at.x = TIME_GRAPH_AREA_BL_X - 2*FONT_SIZE;
++                (t_cfg+i)->at.y = TIME_GRAPH_AREA_TR_Y + (i-1) * ((TIME_GRAPH_AREA_BL_Y - TIME_GRAPH_AREA_TR_Y)/5);//TIME_GRAPH_AREA_TR_Y;
++                strcpy(text[i],string_list[i]);
++        }
++
++#if 1
++        (y_cfg+7)->region.bottom_left.x = EMIF_AREA_BL_X;
++        (y_cfg+7)->region.bottom_left.y = EMIF_AREA_BL_Y;
++        (y_cfg+7)->region.top_right.x = EMIF_AREA_TR_X;
++        (y_cfg+7)->region.top_right.y = EMIF_AREA_TR_Y;
++
++        (t_cfg+7)->at.x = WIDTH_EMIF_AREA/2 - 2*FONT_SIZE;
++        (t_cfg+7)->at.y = EMIF_AREA_TR_Y + FONT_SIZE;
++        strcpy(text[7],string_list[7]);
++
++        for(i=8; i<12; i=i+2)
++        {
++                (y_cfg+i)->region.bottom_left.x = EMIF_AREA_BL_X + BORDER + (i-8)*(BAR_WIDTH+BAR_GAP)/2;
++                (y_cfg+i)->region.bottom_left.y = EMIF_AREA_BL_Y - BORDER/2;// - (i-2) * (30);
++                (y_cfg+i)->region.top_right.x = EMIF_AREA_BL_X + BORDER + BAR_WIDTH + (i-8) * (BAR_WIDTH + BAR_GAP)/2;
++                (y_cfg+i)->region.top_right.y = EMIF_AREA_TR_Y + BORDER * 1.2;
++
++                (y_cfg+i)->fill_color.r = 1.0;
++                (y_cfg+i)->fill_color.g = 0.0;
++                (y_cfg+i)->fill_color.b = 0.0;
++                (y_cfg+i)->fill_color.a = 0.1;
++
++                (y_cfg+i+1)->region.bottom_left.x = EMIF_AREA_BL_X + BORDER + (i-8) * (BAR_WIDTH + BAR_GAP)/2;
++                (y_cfg+i+1)->region.bottom_left.y = EMIF_AREA_BL_Y - BORDER/2;
++                (y_cfg+i+1)->region.top_right.x = EMIF_AREA_BL_X + BORDER + BAR_WIDTH + (i-8) * (BAR_WIDTH + BAR_GAP)/2;
++                (y_cfg+i+1)->region.top_right.y = EMIF_AREA_TR_Y + BORDER*1.2;
++
++                (y_cfg+i+1)->fill_color.r = 0.0;
++                (y_cfg+i+1)->fill_color.g = 1.0;
++                (y_cfg+i+1)->fill_color.b = 0.0;
++                (y_cfg+i+1)->fill_color.a = 1.0;
++
++                (t_cfg+i)->at.x = EMIF_AREA_BL_X + BAR_WIDTH + BORDER + (i-8) * (BAR_WIDTH + BAR_GAP)/2- 2.2*FONT_SIZE;
++                (t_cfg+i)->at.y = EMIF_AREA_TR_Y + BORDER*1.2 -5;
++
++                /* Fixed strings */
++                (t_cfg+i+1)->at.x = EMIF_AREA_BL_X + BORDER + (i-8) * (BAR_WIDTH + BAR_GAP)/2;
++                (t_cfg+i+1)->at.y = EMIF_AREA_BL_Y;// - BORDER + FONT_SIZE;
++
++                strcpy(text[i],string_list[i]);
++                strcpy(text[i+1],string_list[i+1]);
++        }
++
++        (y_cfg+12)->region.bottom_left.x = INITIATORS_AREA_BL_X;
++        (y_cfg+12)->region.bottom_left.y = INITIATORS_AREA_BL_Y;
++        (y_cfg+12)->region.top_right.x = INITIATORS_AREA_TR_X;
++        (y_cfg+12)->region.top_right.y = INITIATORS_AREA_TR_Y;
++
++        (t_cfg+12)->at.x = EMIF_AREA_TR_X + (INITIATORS_AREA_TR_X - INITIATORS_AREA_BL_X)/2 - 4 * FONT_SIZE;
++        (t_cfg+12)->at.y = INITIATORS_AREA_TR_Y + FONT_SIZE;
++        strcpy(text[12],string_list[12]);
++
++        for(i=13; i<25; i=i+2)
++        {
++                (y_cfg+i)->region.bottom_left.x = INITIATORS_AREA_BL_X + BORDER + (i-13)*(BAR_WIDTH+BAR_GAP)/2;
++                (y_cfg+i)->region.bottom_left.y = INITIATORS_AREA_BL_Y - BORDER/2;// - (i-2) * (30);
++                (y_cfg+i)->region.top_right.x = INITIATORS_AREA_BL_X + BORDER + BAR_WIDTH + (i-13) * (BAR_WIDTH + BAR_GAP)/2;
++                (y_cfg+i)->region.top_right.y = INITIATORS_AREA_TR_Y + BORDER*1.2;
++
++                (y_cfg+i)->fill_color.r = 1.0;
++                (y_cfg+i)->fill_color.g = 0.0;
++                (y_cfg+i)->fill_color.b = 0.0;
++                (y_cfg+i)->fill_color.a = 0.1;
++
++                (y_cfg+i+1)->region.bottom_left.x = INITIATORS_AREA_BL_X + BORDER + (i-13) * (BAR_WIDTH + BAR_GAP)/2;
++                (y_cfg+i+1)->region.bottom_left.y = INITIATORS_AREA_BL_Y - BORDER/2;// - (i-2) * (30);
++                (y_cfg+i+1)->region.top_right.x = INITIATORS_AREA_BL_X + BORDER + BAR_WIDTH + (i-13) * (BAR_WIDTH + BAR_GAP)/2;
++                (y_cfg+i+1)->region.top_right.y = INITIATORS_AREA_TR_Y + BORDER* 1.2;
++
++                (y_cfg+i+1)->fill_color.r = 0.0;
++                (y_cfg+i+1)->fill_color.g = 1.0;
++                (y_cfg+i+1)->fill_color.b = 0.0;
++                (y_cfg+i+1)->fill_color.a = 1.0;
++
++                (t_cfg+i)->at.x = INITIATORS_AREA_BL_X + BORDER + BAR_WIDTH + (i-13) * (BAR_WIDTH + BAR_GAP)/2 - 2.2* FONT_SIZE;
++                (t_cfg+i)->at.y = INITIATORS_AREA_TR_Y + BORDER*1.2 -5;
++
++                (t_cfg+i+1)->at.x = INITIATORS_AREA_BL_X + BORDER + (i-13)*(BAR_WIDTH+BAR_GAP)/2;
++                (t_cfg+i+1)->at.y = INITIATORS_AREA_BL_Y;
++
++                strcpy(text[i],string_list[i]);
++                strcpy(text[i+1],string_list[i+1]);
++        }
++#endif
++
++#if 0
++        for(i=0; i<25; i++)
++                printf("(%d, %d) to (%d, %d)\n", (y_cfg +i)->region.bottom_left.x,(y_cfg +i)->region.bottom_left.y,(y_cfg +i)->region.top_right.x, (y_cfg +i)->region.top_right.y);
++#endif
++
++
++
++        for(i=0; i<25; i++) {
++                (t_cfg+i)->color.r = 0.0;
++                (t_cfg+i)->color.g = 1.0;
++                (t_cfg+i)->color.b = 1.0;
++                (t_cfg+i)->color.a = 1.0;
++                (t_cfg+i)->fontsize = FONT_SIZE;
++        }
++                (t_cfg+0)->fontsize = 20;
++
++
++}
++
++
++void statCollectorInit()
++{
++    int index;
++
++    gStatColState.stat0_filter_cnt = 0;
++    gStatColState.stat1_filter_cnt = 0;
++    gStatColState.stat2_filter_cnt = 0;
++    gStatColState.stat3_filter_cnt = 0;
++    gStatColState.stat4_filter_cnt = 0;
++    gStatColState.stat5_filter_cnt = 0;
++    gStatColState.stat6_filter_cnt = 0;
++    gStatColState.stat7_filter_cnt = 0;
++    gStatColState.stat8_filter_cnt = 0;
++    gStatColState.stat9_filter_cnt = 0;
++
++    for(index=STATCOL_EMIF1_SYS; index < STATCOL_MAX; index++)
++    {
++      global_object[index].b_enabled = 0;
++
++      strcpy(global_object[index].name, initiators[index].name); 
++
++      global_object[index].readings = malloc(TRACE_SZ * sizeof(UInt32));
++      memset(global_object[index].readings, 0, TRACE_SZ * sizeof(UInt32));
++
++      global_object[index].timestamp = NULL;
++
++      global_object[index].group_id = 0xFF;
++      global_object[index].counter_id = 0;
++      global_object[index].base_address = 0;
++      global_object[index].mux_req = 0;
++    }
++
++}
++
++void wr_stat_reg(UInt32 address, UInt32 data)
++{
++    UInt32 *mymem = statcoll_base_mem;
++    UInt32 delta = (address - STATCOLL_BASE) / 4;
++#ifndef DUMMY_MODE
++    mymem[delta] = data;
++#else
++    printf("WRITE: Address = 0x%x, Data = 0x%x\n", address, data);
++#endif
++}
++
++UInt32 rd_stat_reg(UInt32 address)
++{
++#ifndef DUMMY_MODE
++    UInt32 *mymem = statcoll_base_mem;
++    UInt32 data;
++    UInt32 delta = (address - STATCOLL_BASE) / 4;
++    data = mymem[delta];
++    return data;
++#else
++    printf("READ: Address = 0x%x\n", address);
++#endif
++}
++
++UInt32 statCollectorControlInitialize(UInt32 instance_id)
++{
++    UInt32 cur_base_address = 0;
++    UInt32 cur_event_mux_req;
++    UInt32 cur_event_mux_resp;
++    UInt32 cur_stat_filter_cnt;
++
++    switch (instance_id)
++    {
++    case STATCOL_EMIF1_SYS:
++        cur_base_address = stat_coll0_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat0_filter_cnt = gStatColState.stat0_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat0_filter_cnt;
++      global_object[instance_id].group_id = 0;
++        break;
++    case STATCOL_EMIF2_SYS:
++        cur_base_address = stat_coll0_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat0_filter_cnt = gStatColState.stat0_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat0_filter_cnt;
++      global_object[instance_id].group_id = 0;
++        break;
++    case STATCOL_MA_MPU_P1:
++        cur_base_address = stat_coll0_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat0_filter_cnt = gStatColState.stat0_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat0_filter_cnt;
++      global_object[instance_id].group_id = 0;
++        break;
++    case STATCOL_MA_MPU_P2:
++        cur_base_address = stat_coll0_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat0_filter_cnt = gStatColState.stat0_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat0_filter_cnt;
++      global_object[instance_id].group_id = 0;
++        break;
++    case STATCOL_MPU1:
++        cur_base_address = stat_coll1_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat1_filter_cnt;
++      global_object[instance_id].group_id = 1;
++        break;
++    case STATCOL_MMU1:
++        cur_base_address = stat_coll1_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat1_filter_cnt;
++      global_object[instance_id].group_id = 1;
++        break;
++    case STATCOL_TPTC_RD1:
++        cur_base_address = stat_coll1_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat1_filter_cnt;
++      global_object[instance_id].group_id = 1;
++        break;
++    case STATCOL_TPTC_WR1:
++        cur_base_address = stat_coll1_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat1_filter_cnt;
++      global_object[instance_id].group_id = 1;
++        break;
++    case STATCOL_TPTC_RD2:
++        cur_base_address = stat_coll1_base_address;
++        cur_event_mux_req = 8;
++        cur_event_mux_resp = 9;
++        gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat1_filter_cnt;
++      global_object[instance_id].group_id = 1;
++        break;
++    case STATCOL_TPTC_WR2:
++        cur_base_address = stat_coll1_base_address;
++        cur_event_mux_req = 10;
++        cur_event_mux_resp = 11;
++        gStatColState.stat1_filter_cnt = gStatColState.stat1_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat1_filter_cnt;
++      global_object[instance_id].group_id = 1;
++        break;
++    case STATCOL_VIP1_P1:
++        cur_base_address = stat_coll2_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat2_filter_cnt;
++      global_object[instance_id].group_id = 2;
++        break;
++    case STATCOL_VIP1_P2:
++        cur_base_address = stat_coll2_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat2_filter_cnt;
++      global_object[instance_id].group_id = 2;
++        break;
++    case STATCOL_VIP2_P1:
++        cur_base_address = stat_coll2_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat2_filter_cnt;
++      global_object[instance_id].group_id = 2;
++        break;
++    case STATCOL_VIP2_P2:
++        cur_base_address = stat_coll2_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat2_filter_cnt;
++      global_object[instance_id].group_id = 2;
++        break;
++    case STATCOL_VIP3_P1:
++        cur_base_address = stat_coll2_base_address;
++        cur_event_mux_req = 8;
++        cur_event_mux_resp = 9;
++        gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat2_filter_cnt;
++      global_object[instance_id].group_id = 2;
++        break;
++    case STATCOL_VIP3_P2:
++        cur_base_address = stat_coll2_base_address;
++        cur_event_mux_req = 10;
++        cur_event_mux_resp = 11;
++        gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat2_filter_cnt;
++      global_object[instance_id].group_id = 2;
++        break;
++    case STATCOL_VPE_P1:
++        cur_base_address = stat_coll2_base_address;
++        cur_event_mux_req = 12;
++        cur_event_mux_resp = 13;
++        gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat2_filter_cnt;
++      global_object[instance_id].group_id = 2;
++        break;
++    case STATCOL_VPE_P2:
++        cur_base_address = stat_coll2_base_address;
++        cur_event_mux_req = 14;
++        cur_event_mux_resp = 15;
++        gStatColState.stat2_filter_cnt = gStatColState.stat2_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat2_filter_cnt;
++      global_object[instance_id].group_id = 2;
++        break;
++    case STATCOL_EVE1_TC0:
++        cur_base_address = stat_coll3_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat3_filter_cnt;
++      global_object[instance_id].group_id = 3;
++        break;
++    case STATCOL_EVE1_TC1:
++        cur_base_address = stat_coll3_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat3_filter_cnt;
++      global_object[instance_id].group_id = 3;
++        break;
++    case STATCOL_EVE2_TC0:
++        cur_base_address = stat_coll3_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat3_filter_cnt;
++      global_object[instance_id].group_id = 3;
++        break;
++    case STATCOL_EVE2_TC1:
++        cur_base_address = stat_coll3_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat3_filter_cnt;
++      global_object[instance_id].group_id = 3;
++        break;
++    case STATCOL_EVE3_TC0:
++        cur_base_address = stat_coll3_base_address;
++        cur_event_mux_req = 8;
++        cur_event_mux_resp = 9;
++        gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat3_filter_cnt;
++      global_object[instance_id].group_id = 3;
++        break;
++    case STATCOL_EVE3_TC1:
++        cur_base_address = stat_coll3_base_address;
++        cur_event_mux_req = 10;
++        cur_event_mux_resp = 11;
++        gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat3_filter_cnt;
++      global_object[instance_id].group_id = 3;
++        break;
++    case STATCOL_EVE4_TC0:
++        cur_base_address = stat_coll3_base_address;
++        cur_event_mux_req = 12;
++        cur_event_mux_resp = 13;
++        gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat3_filter_cnt;
++      global_object[instance_id].group_id = 3;
++        break;
++    case STATCOL_EVE4_TC1:
++        cur_base_address = stat_coll3_base_address;
++        cur_event_mux_req = 14;
++        cur_event_mux_resp = 15;
++        gStatColState.stat3_filter_cnt = gStatColState.stat3_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat3_filter_cnt;
++      global_object[instance_id].group_id = 3;
++        break;
++    case STATCOL_DSP1_MDMA:
++        cur_base_address = stat_coll4_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat4_filter_cnt;
++      global_object[instance_id].group_id = 4;
++        break;
++    case STATCOL_DSP1_EDMA:
++        cur_base_address = stat_coll4_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat4_filter_cnt;
++      global_object[instance_id].group_id = 4;
++        break;
++    case STATCOL_DSP2_MDMA:
++        cur_base_address = stat_coll4_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat4_filter_cnt;
++      global_object[instance_id].group_id = 4;
++        break;
++    case STATCOL_DSP2_EDMA:
++        cur_base_address = stat_coll4_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat4_filter_cnt;
++      global_object[instance_id].group_id = 4;
++        break;
++    case STATCOL_IVA:
++        cur_base_address = stat_coll4_base_address;
++        cur_event_mux_req = 8;
++        cur_event_mux_resp = 9;
++        gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat4_filter_cnt;
++      global_object[instance_id].group_id = 4;
++        break;
++    case STATCOL_GPU_P1:
++        cur_base_address = stat_coll4_base_address;
++        cur_event_mux_req = 10;
++        cur_event_mux_resp = 11;
++        gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat4_filter_cnt;
++      global_object[instance_id].group_id = 4;
++        break;
++    case STATCOL_GPU_P2:
++        cur_base_address = stat_coll4_base_address;
++        cur_event_mux_req = 12;
++        cur_event_mux_resp = 13;
++        gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat4_filter_cnt;
++      global_object[instance_id].group_id = 4;
++        break;
++    case STATCOL_BB2D_P1:
++        cur_base_address = stat_coll4_base_address;
++        cur_event_mux_req = 14;
++        cur_event_mux_resp = 15;
++        gStatColState.stat4_filter_cnt = gStatColState.stat4_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat4_filter_cnt;
++      global_object[instance_id].group_id = 4;
++        break;
++    case STATCOL_DSS:
++        cur_base_address = stat_coll5_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat5_filter_cnt;
++      global_object[instance_id].group_id = 5;
++        break;
++    case STATCOL_CSI2_2:
++        cur_base_address = stat_coll5_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat5_filter_cnt;
++      global_object[instance_id].group_id = 5;
++        break;
++    case STATCOL_MMU2:
++        cur_base_address = stat_coll5_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat5_filter_cnt;
++      global_object[instance_id].group_id = 5;
++        break;
++    case STATCOL_IPU1:
++        cur_base_address = stat_coll5_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat5_filter_cnt;
++      global_object[instance_id].group_id = 5;
++        break;
++    case STATCOL_IPU2:
++        cur_base_address = stat_coll5_base_address;
++        cur_event_mux_req = 8;
++        cur_event_mux_resp = 9;
++        gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat5_filter_cnt;
++      global_object[instance_id].group_id = 5;
++        break;
++    case STATCOL_DMA_SYSTEM_RD:
++        cur_base_address = stat_coll5_base_address;
++        cur_event_mux_req = 10;
++        cur_event_mux_resp = 11;
++        gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat5_filter_cnt;
++      global_object[instance_id].group_id = 5;
++        break;
++    case STATCOL_DMA_SYSTEM_WR:
++        cur_base_address = stat_coll5_base_address;
++        cur_event_mux_req = 12;
++        cur_event_mux_resp = 13;
++        gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat5_filter_cnt;
++      global_object[instance_id].group_id = 5;
++        break;
++    case STATCOL_CSI2_1:
++        cur_base_address = stat_coll5_base_address;
++        cur_event_mux_req = 14;
++        cur_event_mux_resp = 15;
++        gStatColState.stat5_filter_cnt = gStatColState.stat5_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat5_filter_cnt;
++      global_object[instance_id].group_id = 5;
++        break;
++    case STATCOL_USB3_SS:
++        cur_base_address = stat_coll6_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat6_filter_cnt;
++      global_object[instance_id].group_id = 6;
++        break;
++    case STATCOL_USB2_SS:
++        cur_base_address = stat_coll6_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat6_filter_cnt;
++      global_object[instance_id].group_id = 6;
++        break;
++    case STATCOL_USB2_ULPI_SS1:
++        cur_base_address = stat_coll6_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat6_filter_cnt;
++      global_object[instance_id].group_id = 6;
++        break;
++    case STATCOL_USB2_ULPI_SS2:
++        cur_base_address = stat_coll6_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat6_filter_cnt;
++      global_object[instance_id].group_id = 6;
++        break;
++    case STATCOL_PCIE_SS1:
++        cur_base_address = stat_coll6_base_address;
++        cur_event_mux_req = 8;
++        cur_event_mux_resp = 9;
++        gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat6_filter_cnt;
++      global_object[instance_id].group_id = 6;
++        break;
++    case STATCOL_PCIE_SS2:
++        cur_base_address = stat_coll6_base_address;
++        cur_event_mux_req = 10;
++        cur_event_mux_resp = 11;
++        gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat6_filter_cnt;
++      global_object[instance_id].group_id = 6;
++        break;
++    case STATCOL_DSP1_CFG:
++        cur_base_address = stat_coll6_base_address;
++        cur_event_mux_req = 12;
++        cur_event_mux_resp = 13;
++        gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat6_filter_cnt;
++      global_object[instance_id].group_id = 6;
++        break;
++    case STATCOL_DSP2_CFG:
++        cur_base_address = stat_coll6_base_address;
++        cur_event_mux_req = 14;
++        cur_event_mux_resp = 15;
++        gStatColState.stat6_filter_cnt = gStatColState.stat6_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat6_filter_cnt;
++      global_object[instance_id].group_id = 6;
++        break;
++    case STATCOL_GMAC_SW:
++        cur_base_address = stat_coll7_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat7_filter_cnt;
++      global_object[instance_id].group_id = 7;
++        break;
++    case STATCOL_PRUSS1_P1:
++        cur_base_address = stat_coll7_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat7_filter_cnt;
++      global_object[instance_id].group_id = 7;
++        break;
++    case STATCOL_PRUSS1_P2:
++        cur_base_address = stat_coll7_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat7_filter_cnt;
++      global_object[instance_id].group_id = 7;
++        break;
++    case STATCOL_PRUSS2_P1:
++        cur_base_address = stat_coll7_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat7_filter_cnt;
++      global_object[instance_id].group_id = 7;
++        break;
++    case STATCOL_PRUSS2_P2:
++        cur_base_address = stat_coll7_base_address;
++        cur_event_mux_req = 8;
++        cur_event_mux_resp = 9;
++        gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat7_filter_cnt;
++      global_object[instance_id].group_id = 7;
++        break;
++    case STATCOL_DMA_CRYPTO_RD:
++        cur_base_address = stat_coll7_base_address;
++        cur_event_mux_req = 10;
++        cur_event_mux_resp = 11;
++        gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat7_filter_cnt;
++      global_object[instance_id].group_id = 7;
++        break;
++    case STATCOL_DMA_CRYPTO_WR:
++        cur_base_address = stat_coll7_base_address;
++        cur_event_mux_req = 12;
++        cur_event_mux_resp = 13;
++        gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat7_filter_cnt;
++      global_object[instance_id].group_id = 7;
++        break;
++    case STATCOL_MPU2:
++        cur_base_address = stat_coll7_base_address;
++        cur_event_mux_req = 14;
++        cur_event_mux_resp = 15;
++        gStatColState.stat7_filter_cnt = gStatColState.stat7_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat7_filter_cnt;
++      global_object[instance_id].group_id = 7;
++        break;
++    case STATCOL_MMC1:
++        cur_base_address = stat_coll8_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat8_filter_cnt;
++      global_object[instance_id].group_id = 8;
++        break;
++    case STATCOL_MMC2:
++        cur_base_address = stat_coll8_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat8_filter_cnt;
++      global_object[instance_id].group_id = 8;
++        break;
++    case STATCOL_SATA:
++        cur_base_address = stat_coll8_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat8_filter_cnt;
++      global_object[instance_id].group_id = 8;
++        break;
++    case STATCOL_MLBSS:
++        cur_base_address = stat_coll8_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat8_filter_cnt;
++      global_object[instance_id].group_id = 8;
++        break;
++    case STATCOL_BB2D_P2:
++        cur_base_address = stat_coll8_base_address;
++        cur_event_mux_req = 8;
++        cur_event_mux_resp = 9;
++        gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat8_filter_cnt;
++      global_object[instance_id].group_id = 8;
++        break;
++    case STATCOL_IEEE1500:
++        cur_base_address = stat_coll8_base_address;
++        cur_event_mux_req = 10;
++        cur_event_mux_resp = 11;
++        gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat8_filter_cnt;
++      global_object[instance_id].group_id = 8;
++        break;
++    case STATCOL_DBG:
++        cur_base_address = stat_coll8_base_address;
++        cur_event_mux_req = 12;
++        cur_event_mux_resp = 13;
++        gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat8_filter_cnt;
++      global_object[instance_id].group_id = 8;
++        break;
++    case STATCOL_VCP1:
++        cur_base_address = stat_coll8_base_address;
++        cur_event_mux_req = 14;
++        cur_event_mux_resp = 15;
++        gStatColState.stat8_filter_cnt = gStatColState.stat8_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat8_filter_cnt;
++      global_object[instance_id].group_id = 8;
++        break;
++    case STATCOL_OCMC_RAM1:
++        cur_base_address = stat_coll9_base_address;
++        cur_event_mux_req = 0;
++        cur_event_mux_resp = 1;
++        gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat9_filter_cnt;
++      global_object[instance_id].group_id = 9;
++        break;
++    case STATCOL_OCMC_RAM2:
++        cur_base_address = stat_coll9_base_address;
++        cur_event_mux_req = 2;
++        cur_event_mux_resp = 3;
++        gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat9_filter_cnt;
++      global_object[instance_id].group_id = 9;
++        break;
++    case STATCOL_OCMC_RAM3:
++        cur_base_address = stat_coll9_base_address;
++        cur_event_mux_req = 4;
++        cur_event_mux_resp = 5;
++        gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat9_filter_cnt;
++      global_object[instance_id].group_id = 9;
++        break;
++    case STATCOL_GPMC:
++        cur_base_address = stat_coll9_base_address;
++        cur_event_mux_req = 6;
++        cur_event_mux_resp = 7;
++        gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat9_filter_cnt;
++      global_object[instance_id].group_id = 9;
++        break;
++    case STATCOL_MCASP1:
++        cur_base_address = stat_coll9_base_address;
++        cur_event_mux_req = 8;
++        cur_event_mux_resp = 9;
++        gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat9_filter_cnt;
++      global_object[instance_id].group_id = 9;
++        break;
++    case STATCOL_MCASP2:
++        cur_base_address = stat_coll9_base_address;
++        cur_event_mux_req = 10;
++        cur_event_mux_resp = 11;
++        gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat9_filter_cnt;
++      global_object[instance_id].group_id = 9;
++        break;
++    case STATCOL_MCASP3:
++        cur_base_address = stat_coll9_base_address;
++        cur_event_mux_req = 12;
++        cur_event_mux_resp = 13;
++        gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat9_filter_cnt;
++      global_object[instance_id].group_id = 9;
++        break;
++    case STATCOL_VCP2:
++        cur_base_address = stat_coll9_base_address;
++        cur_event_mux_req = 14;
++        cur_event_mux_resp = 15;
++        gStatColState.stat9_filter_cnt = gStatColState.stat9_filter_cnt + 1;
++        cur_stat_filter_cnt = gStatColState.stat9_filter_cnt;
++      global_object[instance_id].group_id = 9;
++        break;
++    default:
++       printf("ERROR: Unknown initiator %d\n", instance_id);
++       exit(0);
++    };
++
++    {
++        if ( cur_stat_filter_cnt > 4 )
++        {
++            printf("WARNING: We have exhausted filters/counters.....\n");
++            return 0;
++        }
++        // Global Enable Stat Collector
++        wr_stat_reg(cur_base_address+0x8,0x1);
++
++        // Soft Enable Stat Collector
++        wr_stat_reg(cur_base_address+0xC,0x1);
++
++        wr_stat_reg(cur_base_address+0x18,0x5);
++        // Operation of Stat Collector / RespEvt => Packet
++        wr_stat_reg(cur_base_address+0x1C,0x5);
++
++
++        // Event Sel
++        wr_stat_reg(cur_base_address+0x20+4*(cur_stat_filter_cnt-1),cur_event_mux_req);
++
++        // Op is EventInfo
++        wr_stat_reg(cur_base_address+0x1FC+(0x158*(cur_stat_filter_cnt-1)),2);
++
++        // Event Info Sel Op -> packet length
++        wr_stat_reg(cur_base_address+0x1F8+(0x158*(cur_stat_filter_cnt-1)),0);
++
++        // Filter Global Enable
++        wr_stat_reg(cur_base_address+0xAC+(0x158*(cur_stat_filter_cnt-1)),0x1);
++
++        // Filter Enable
++        wr_stat_reg(cur_base_address+0xBC+(0x158*(cur_stat_filter_cnt-1)),0x1);
++
++        // Manual dump
++        wr_stat_reg(cur_base_address+0x54,0x1);
++        // use send register to reset counters
++
++    }
++
++    global_object[instance_id].mux_req = cur_event_mux_req;
++    global_object[instance_id].base_address = cur_base_address;
++    global_object[instance_id].counter_id = cur_stat_filter_cnt;
++    global_object[instance_id].b_enabled = 1;
++
++    return cur_stat_filter_cnt;
++}
++
++
++
++void statCollectorReadGroup(UInt32 group_id)
++{
++    int i=0;
++    UInt32 cur_base_address = 0x45001000 + ((group_id - 1) * 0x1000);
++
++    wr_stat_reg(cur_base_address+0xC,0x0);
++
++    for(i=0; i < STATCOL_MAX; i++)
++    {
++      if(global_object[i].group_id == (group_id - 1) && 
++         global_object[i].b_enabled == 1)
++      {
++          UInt32 cur_stat_filter_cnt = global_object[i].counter_id;
++
++          global_object[i].readings[statCountIdx] = rd_stat_reg(cur_base_address+0x8C+((cur_stat_filter_cnt-1)*4));
++        }
++    }
++
++    wr_stat_reg(cur_base_address+0xC,0x1);
++}
++
++
++volatile sig_atomic_t sigtermed = 0;
++
++void my_signal_handler(int signum)
++{
++      if (signum == SIGTERM || signum == SIGINT) {
++              sigtermed = 1;
++      }
++}
++
++struct sort
++{
++      int pos;
++      double value;
++};
++
++
++void *ctx;
++struct time_graph_create_params p;
++char xpos_string[100], ypos_string[100];
++
++void mpu_handler(int command)
++{
++#if 1
++        static int fd;
++        char buf[1000];
++        char * tabledata= "/tmp/statcollfifo";
++        int i;
++        int bytes;
++        static int offset = 13;
++
++        switch(command)
++        {
++                case OPEN:
++                        fd = open(tabledata, O_RDONLY|O_NONBLOCK);
++                        break;
++
++                case READ:
++
++                        /* open, read, and display the message from the FIFO */
++                        bytes=read(fd, buf, 1000);
++                        if(bytes > 0)
++                        {
++                                char str[100];
++                                char value[100];
++                                sscanf(buf, "%s %s", str, value);
++                                if(strcmp(str, "MOVE:") == 0)
++                                {
++                                        printf("Received MOVE command : %s\n", buf);
++                                        sprintf(p.title, "CPU Usage[@position-req=%sx%s]", value, ypos_string);
++                                        move_graph(ctx, &p);
++                                }
++                                else
++                                {
++                                        printf("ERROR: Received unexpected data from FIFO - \" %s \" \n", buf);
++                                }
++                                memset(buf, 0x0, sizeof(buf));
++                        }
++
++                        break;
++
++                case CLOSE:
++                        close(fd);
++                        break;
++        }
++#endif
++        return;
++}
++
++
++UInt32 statcoll_start(UInt32 TOTAL_TIME, UInt32 INTERVAL_US, char list[][50], UInt32 xpos, UInt32 ypos)
++{
++    int i, fd, index;
++    UInt32 counterIdDss, counterIdIva, counterIdBB2dP1, counterIdBB2dP2, counterIdUsb4, counterIdSata, counterIdEmif1, counterIdEmif2;
++
++    if (SIG_ERR == signal(SIGPIPE,SIG_IGN))
++          exit(1);
++
++    if (SIG_ERR == signal(SIGINT,my_signal_handler))
++          exit(1);
++
++    if (SIG_ERR == signal(SIGTERM,my_signal_handler))
++          exit(1);
++
++  
++    struct timeval tv1, tv2;
++    gettimeofday(&tv1, NULL);
++    printf("------------------------------------------------\n");
++    printf("Compile time = %s %s\n",__DATE__,  __TIME__);
++    printf("------------------------------------------------\n\n");
++    //printd("Start time = %d\n", time(NULL));
++    //printd("Time seconds = %d, usecs = %d\n", tv.tv_sec, tv.tv_usec);
++
++    statcoll_params params;
++    memset(&params, sizeof(params), 0);
++    params.INTERVAL_US = INTERVAL_US;
++    params.TOTAL_TIME = TOTAL_TIME;
++
++    i=0;
++    index=0;
++
++    while(list[i][0] != 0)
++    {
++      for(index=0; index< STATCOL_MAX; index++) {
++              if(strcmp(list[i], initiators[index].name) == 0)
++              {
++                      strcpy(params.user_config_list[params.no_of_initiators].name, list[i]);
++                      params.user_config_list[params.no_of_initiators++].id = initiators[index].id;
++                      break;
++              }
++      }
++
++      if(index == STATCOL_MAX) {
++              printf("ERROR: Unknown initiator.%d.. .%s. \n", i, list[i]);
++              //exit(0);
++      }
++        i++;
++    }
++
++      struct bar_graph_create_params bg_p;
++      struct _y_config *y_cfg;
++      struct _text_config *t_cfg;
++      double *y;
++      double *bg_y;
++        char *text_list[STATCOL_MAX];
++
++        struct _bar_graph_y_config *bg_y_cfg;
++        struct _text_config *bg_t_cfg;
++      char *bg_text_list[STATCOL_MAX];
++      
++      sprintf(xpos_string, "%d", xpos);
++      sprintf(ypos_string, "%d", ypos);
++      p.title=(char *)malloc(100);
++      sprintf(p.title, "CPU Usage[@position-req=%sx%s]", xpos_string, ypos_string);
++      //p.height = MAX_HEIGHT - HEIGHT_EMIF_AREA;
++      p.height = MAX_HEIGHT;// - HEIGHT_EMIF_AREA;
++      p.width = MAX_WIDTH;
++      p.draw_area.bottom_left.x = TIME_GRAPH_AREA_BL_X;
++      p.draw_area.bottom_left.y = TIME_GRAPH_AREA_BL_Y;
++      p.draw_area.top_right.x = TIME_GRAPH_AREA_TR_X;
++      p.draw_area.top_right.y = TIME_GRAPH_AREA_TR_Y;
++      p.time_span = 120000; // 120 seconds
++      p.num_of_y_items = params.no_of_initiators+1;
++      p.num_of_text_items = 0;//params.no_of_initiators;
++
++
++      y_cfg = malloc((params.no_of_initiators+1) * sizeof(struct _y_config));
++      t_cfg = malloc(params.no_of_initiators * sizeof(struct _text_config));
++      y = malloc((params.no_of_initiators+1) * sizeof(double));
++      p.y_config_array = y_cfg;
++      p.text_config_array = t_cfg;
++
++      bg_y_cfg = malloc(TOTAL_Y_PARAMETERS * sizeof(struct _bar_graph_y_config));
++      bg_t_cfg = malloc(TOTAL_Y_PARAMETERS * sizeof(struct _text_config));
++      bg_y = malloc(TOTAL_Y_PARAMETERS * sizeof(double));
++
++       for(i=0; i<TOTAL_Y_PARAMETERS; i++)
++       {
++               bg_text_list[i] = malloc(100);
++               strcpy(bg_text_list[i],"test");
++       }
++
++       create_overall_box(bg_y_cfg, bg_t_cfg, bg_text_list);
++
++
++      i=0;
++      while(i < params.no_of_initiators)
++      {
++              text_list[i] = malloc(100 * sizeof(char));
++              memset(text_list[i], 0x0, 100);
++
++              ((struct _y_config *)y_cfg+i)->line_color.r = pallette[i%MAX_COLORS].r;
++              ((struct _y_config *)y_cfg+i)->line_color.g = pallette[i%MAX_COLORS].g;
++              ((struct _y_config *)y_cfg+i)->line_color.b = pallette[i%MAX_COLORS].b;
++              ((struct _y_config *)y_cfg+i)->line_color.a = 0.0;//pallette[i%MAX_COLORS].a;
++              
++              ((struct _y_config *)y_cfg+i)->fill_color.r = 0.0;
++              ((struct _y_config *)y_cfg+i)->fill_color.g = 1.0;
++              ((struct _y_config *)y_cfg+i)->fill_color.b = 0.0;
++              ((struct _y_config *)y_cfg+i)->fill_color.a = 0.5;
++              
++              i++;
++      }
++
++      ((struct _y_config *)y_cfg+i)->line_color.r = 0.0;
++      ((struct _y_config *)y_cfg+i)->line_color.g = 0.0;
++      ((struct _y_config *)y_cfg+i)->line_color.b = 0.0;
++      ((struct _y_config *)y_cfg+i)->line_color.a = 0.5;
++      ((struct _y_config *)y_cfg+i)->fill_color.r = 0.1;
++      ((struct _y_config *)y_cfg+i)->fill_color.g = 0.9;
++      ((struct _y_config *)y_cfg+i)->fill_color.b = 0.5;
++      ((struct _y_config *)y_cfg+i)->fill_color.a = 1.0;
++
++        bg_p.title = "CPU Usage";
++      
++        bg_p.num_of_y_items = TOTAL_Y_PARAMETERS;
++        bg_p.y_config_array = bg_y_cfg;
++        bg_p.num_of_text_items = TOTAL_Y_PARAMETERS;
++        bg_p.text_config_array = bg_t_cfg;
++
++
++      int argc;
++      char *argv[10];
++      ctx = time_graph_create(argc, argv, &p);
++      if (!ctx) {
++              printf("Error creating context\n");
++              exit(0);
++      }
++
++      printf("\n Context after time_graph_create = 0x%x\n", ctx);
++      ctx = bar_graph_create(argc, argv, &bg_p);
++      if (!ctx) {
++              printf("Error creating context\n");
++              exit(0);
++      }
++
++      printf("\n Context after bar_graph_create= 0x%x\n", ctx);
++
++    printf("Total configured initiators = %d\n", params.no_of_initiators);
++      
++
++    fd = open("/dev/mem", O_RDWR);
++    if (fd == -1){
++       printf("error fd=open() \n");     
++       return -1;
++    }
++    statcoll_base_mem = mmap(NULL, STATCOLL_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, STATCOLL_BASE);
++    
++   if (statcoll_base_mem == MAP_FAILED){
++        printf("ERROR: mmap failed \n");
++        return;
++    }
++    close(fd);
++
++    fd = open("/dev/mem", O_RDWR);
++    if (fd == -1){
++       printf("error fd=open() \n");     
++       return -1;
++    }
++    l3_3_clkctrl = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CM_L3INSTR_REGISTER_BASE);
++    if (l3_3_clkctrl == MAP_FAILED){
++        printf("ERROR: mmap failed for CM_L3INSTR_REGISTER_BASE\n");
++        return;
++    }
++    close(fd);
++
++    printf("SUCCESS: Mapped 0x%x to user space address 0x%x\n", STATCOLL_BASE, statcoll_base_mem);
++    printf("INTERVAL = %d usecs\n", INTERVAL_US);
++    printf("TOTAL TIME = %d seconds\n", TOTAL_TIME);
++    TRACE_SZ = (TOTAL_TIME * 1000000)/INTERVAL_US;
++    printf("TRACE SIZE = %d samples\n", TRACE_SZ);
++
++    printf("**************************************\n");
++    printf("Going to initialize the L3 clocks \n"); 
++    l3_3_clkctrl[CM_L3INSTR_L3INSTR_CLKSTCTRL_OFFSET >> 2] = 0x2;
++    l3_3_clkctrl[CM_L3INSTR_L3_MAIN_2_CLKCTRL_OFFSET >> 2] = 0x1;
++    printf("**************************************\n");
++
++    while( (l3_3_clkctrl[CM_L3INSTR_L3_MAIN_2_CLKCTRL_OFFSET >> 2] & 0x30000) != 0x0) 
++    {
++      printf("Waiting on module to be functional\n");
++    }
++
++    statCollectorInit();
++
++    printf("SUCCESS: Initialized STAT COLLECTOR\n");
++    /* Initialize all enabled initiators */
++    for(index =0; index < params.no_of_initiators; index++) {
++        printf("\t\t Initialized %s\n", params.user_config_list[index].name);
++        statCollectorControlInitialize(params.user_config_list[index].id);
++    }
++
++      const char *bg_text = "CPU Utilization";
++
++    int second_counter=0;
++    memset(y, 0x0, sizeof(double)* (params.no_of_initiators+1));
++
++
++
++
++    mpu_handler(OPEN);
++
++
++    while(statCountIdx != (TRACE_SZ - 1))
++    {
++        usleep(INTERVAL_US);
++        int group;
++      for(group = 1; group<11; group++)
++              statCollectorReadGroup(group);
++
++        mpu_handler(READ);
++
++      if(statCountIdx != 0 ) 
++      for(i=0; i<params.no_of_initiators; i++) {
++              y[i] += (double)(global_object[params.user_config_list[i].id].readings[statCountIdx])/ (8000000000);
++      }
++      second_counter++;
++
++      if(second_counter % 30 == 0)
++      {
++              
++              for(i=0; i<TOTAL_Y_PARAMETERS; i++) {
++                      bg_y[i] = 1.0;
++              }
++
++              //HACK
++              bg_y[9]=y[0]*2;
++              bg_y[11]=y[1]*2;
++              sprintf(bg_text_list[8], "%02.1f%s", y[0]*100, "%");
++              sprintf(bg_text_list[10], "%02.1f%s", y[1]*100, "%");
++
++              struct sort sort_array[STATCOL_MAX];
++              memset(sort_array, 0x0, sizeof(struct sort) * STATCOL_MAX);
++              /* Sort here */
++              for(i=2; i<params.no_of_initiators; i++) {
++                      sort_array[i-2].value = y[i];
++                      sort_array[i-2].pos = i;
++              }
++
++              int j;
++              double tempdouble;
++              int tempint;
++              for(i=0; i<params.no_of_initiators-2; i++) {
++                      for(j=i+1; j<params.no_of_initiators-2; j++) { 
++                              if(sort_array[i].value < sort_array[j].value) {
++                                      tempdouble = sort_array[j].value;
++                                      tempint = sort_array[j].pos;
++ 
++                                      sort_array[j].value  = sort_array[i].value;
++                                      sort_array[j].pos    = sort_array[i].pos;
++
++                                      sort_array[i].value = tempdouble;
++                                      sort_array[i].pos   = tempint;
++                              }
++                      }
++              }
++
++              for(i=0; i<6; i++)
++              {
++                      //HACK
++                      bg_y[14+i*2] = sort_array[i].value*2;
++                      sprintf(bg_text_list[13+i*2], "%02.1f%s", sort_array[i].value*100, "%");
++                      sprintf(bg_text_list[14+i*2], "%s", (params.user_config_list[sort_array[i].pos].name)+8);
++              }
++
++                bar_graph_plot(ctx, bg_y, (const char **)bg_text_list);
++
++              y[params.no_of_initiators]=y[0]+y[1];
++              time_graph_plot(ctx, y, (const char **)text_list);
++              //printf("Plotting the time_graph\n");
++              memset(y, 0x0, sizeof(double)* (params.no_of_initiators+1));
++      }
++      statCountIdx++;
++
++    }
++    
++    mpu_handler(CLOSE);
++
++    printf("------------------------------------------------\n\n");
++    printf("SUCCESS: Stat collection completed... Writing into file now\n");
++    FILE *outfile = fopen("statcollector.csv", "w+");
++    if (!outfile) {
++        printf("\n ERROR: Error opening file");
++    }
++
++    /* Ignore the first index at 0 */
++    for(index=1; index<statCountIdx; index++) {
++          for(i=0; i<params.no_of_initiators; i++) {
++                  fprintf(outfile,"%s = %d,", params.user_config_list[i].name, global_object[params.user_config_list[i].id].readings[index]);
++          }
++          fprintf(outfile,"\n"); 
++    }
++    fclose(outfile);
++
++      time_graph_destroy(ctx);
++    gettimeofday(&tv2, NULL);
++    //printf("End time = %d\n", time(NULL));
++    //printf("Time seconds = %d, usecs = %d\n", tv.tv_sec, tv.tv_usec);
++    printf("Total execution time = %d secs, %d usecs\n\n", (tv2.tv_sec - tv1.tv_sec), (tv2.tv_usec - tv2.tv_usec));
++
++    return 0;
++}
++
++
+diff --git a/clients/statcoll.h b/clients/statcoll.h
+new file mode 100644
+index 0000000..fa92753
+--- /dev/null
++++ b/clients/statcoll.h
+@@ -0,0 +1,152 @@
++#ifndef __STATCOLL_H 
++#define __STATCOLL_H
++ 
++
++#define CM_L3INSTR_REGISTER_BASE           (0x4A008000)
++
++#define CM_L3INSTR_L3INSTR_CLKSTCTRL_OFFSET     (0xE00)
++#define CM_L3INSTR_L3_MAIN_2_CLKCTRL_OFFSET     (0xE20)
++
++#define STATCOLL_SIZE 40960
++#define STATCOLL_BASE (0x45001000)
++
++#define stat_coll0_base_address (0x45001000)
++#define stat_coll1_base_address (0x45002000)
++#define stat_coll2_base_address (0x45003000)
++#define stat_coll3_base_address (0x45004000)
++#define stat_coll4_base_address (0x45005000)
++#define stat_coll5_base_address (0x45006000)
++#define stat_coll6_base_address (0x45007000)
++#define stat_coll7_base_address (0x45008000)
++#define stat_coll8_base_address (0x45009000)
++#define stat_coll9_base_address (0x4500a000)
++
++#define printd(fmt, ...) \
++      do { if (debug) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
++
++typedef unsigned int UInt32;
++
++
++typedef enum
++{
++    STATCOL_EMIF1_SYS,
++    STATCOL_EMIF2_SYS,
++    STATCOL_MA_MPU_P1,
++    STATCOL_MA_MPU_P2,
++    STATCOL_MPU1,
++    STATCOL_MMU1,
++    STATCOL_TPTC_RD1,
++    STATCOL_TPTC_WR1,
++    STATCOL_TPTC_RD2,
++    STATCOL_TPTC_WR2,
++    STATCOL_VIP1_P1,
++    STATCOL_VIP1_P2,
++    STATCOL_VIP2_P1,
++    STATCOL_VIP2_P2,
++    STATCOL_VIP3_P1,
++    STATCOL_VIP3_P2,
++    STATCOL_VPE_P1,
++    STATCOL_VPE_P2,
++    STATCOL_EVE1_TC0,
++    STATCOL_EVE1_TC1,
++    STATCOL_EVE2_TC0,
++    STATCOL_EVE2_TC1,
++    STATCOL_EVE3_TC0,
++    STATCOL_EVE3_TC1,
++    STATCOL_EVE4_TC0,
++    STATCOL_EVE4_TC1,
++    STATCOL_DSP1_MDMA,
++    STATCOL_DSP1_EDMA,
++    STATCOL_DSP2_MDMA,
++    STATCOL_DSP2_EDMA,
++    STATCOL_IVA,
++    STATCOL_GPU_P1,
++    STATCOL_GPU_P2,
++    STATCOL_BB2D_P1,
++    STATCOL_DSS,
++    STATCOL_CSI2_2,
++    STATCOL_MMU2,
++    STATCOL_IPU1,
++    STATCOL_IPU2,
++    STATCOL_DMA_SYSTEM_RD,
++    STATCOL_DMA_SYSTEM_WR,
++    STATCOL_CSI2_1,
++    STATCOL_USB3_SS,
++    STATCOL_USB2_SS,
++    STATCOL_USB2_ULPI_SS1,
++    STATCOL_USB2_ULPI_SS2,
++    STATCOL_PCIE_SS1,
++    STATCOL_PCIE_SS2,
++    STATCOL_DSP1_CFG,
++    STATCOL_DSP2_CFG,
++    STATCOL_GMAC_SW,
++    STATCOL_PRUSS1_P1,
++    STATCOL_PRUSS1_P2,
++    STATCOL_PRUSS2_P1,
++    STATCOL_PRUSS2_P2,
++    STATCOL_DMA_CRYPTO_RD,
++    STATCOL_DMA_CRYPTO_WR,
++    STATCOL_MPU2,
++    STATCOL_MMC1,
++    STATCOL_MMC2,
++    STATCOL_SATA,
++    STATCOL_MLBSS,
++    STATCOL_BB2D_P2,
++    STATCOL_IEEE1500,
++    STATCOL_DBG,
++    STATCOL_VCP1,
++    STATCOL_OCMC_RAM1,
++    STATCOL_OCMC_RAM2,
++    STATCOL_OCMC_RAM3,
++    STATCOL_GPMC,
++    STATCOL_MCASP1,
++    STATCOL_MCASP2,
++    STATCOL_MCASP3,
++    STATCOL_VCP2,
++    STATCOL_MAX
++} STATCOL_ID;
++
++
++
++typedef struct
++{
++    UInt32 stat0_filter_cnt;
++    UInt32 stat1_filter_cnt;
++    UInt32 stat2_filter_cnt;
++    UInt32 stat3_filter_cnt;
++    UInt32 stat4_filter_cnt;
++    UInt32 stat5_filter_cnt;
++    UInt32 stat6_filter_cnt;
++    UInt32 stat7_filter_cnt;
++    UInt32 stat8_filter_cnt;
++    UInt32 stat9_filter_cnt;
++} StatCollectorObj;
++ 
++struct list_of_initiators
++{
++   STATCOL_ID id;
++   char name[50];    
++};
++
++typedef struct 
++{
++    UInt32 INTERVAL_US;
++    UInt32 TOTAL_TIME;
++    UInt32 no_of_initiators;
++    struct list_of_initiators user_config_list[STATCOL_MAX];
++} statcoll_params;
++
++typedef struct
++{
++    UInt32 b_enabled;
++    char name[100];
++    UInt32 *readings;
++    UInt32 *timestamp;
++    UInt32 group_id;
++    UInt32 counter_id;
++    UInt32 base_address;
++    UInt32 mux_req;
++}statcoll_initiators_object;
++
++
++#endif
+diff --git a/clients/statcoll_gui.h b/clients/statcoll_gui.h
+new file mode 100644
+index 0000000..7362bde
+--- /dev/null
++++ b/clients/statcoll_gui.h
+@@ -0,0 +1,101 @@
++
++/*
++
++ ---------------------------------------------
++ |                                            |
++ |  ---------------------------------------   |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ |                                            |
++ ---------------------------------------------
++ |           |                                |
++ |           |                                |
++ |           |                                |
++ |           |                                |
++ |           |                                |
++ |           |                                |
++ ---------------------------------------------
++
++
++
++
++*/
++#define POSITION_X 2800
++#define POSITION_Y 40
++
++#define MAX_WIDTH  900
++//#define MAX_WIDTH  528
++#define MAX_HEIGHT 900
++
++/* Derived parameters */
++#define BAR_GAP    (MAX_WIDTH/25)
++#define BAR_WIDTH  (MAX_WIDTH/16)
++
++#define BAR_HEIGHT ((MX_HEIGHT/40) * 6)
++
++#define BORDER     (MAX_WIDTH/15)
++
++#define HEIGHT_EMIF_AREA (MAX_HEIGHT/4)
++
++#define FONT_SIZE (MAX_WIDTH/40)
++
++#define WIDTH_EMIF_AREA (MAX_WIDTH / 4)
++
++#define TOTAL_Y_PARAMETERS (25)
++
++#define TIME_GRAPH_AREA_BL_X (BORDER)
++#define TIME_GRAPH_AREA_BL_Y (MAX_HEIGHT - HEIGHT_EMIF_AREA - BORDER)
++#define TIME_GRAPH_AREA_TR_X (MAX_WIDTH - BORDER)
++#define TIME_GRAPH_AREA_TR_Y (BORDER)
++
++#define EMIF_AREA_BL_X (0)
++#define EMIF_AREA_BL_Y (MAX_HEIGHT)
++#define EMIF_AREA_TR_X (WIDTH_EMIF_AREA)
++#define EMIF_AREA_TR_Y (MAX_HEIGHT - HEIGHT_EMIF_AREA)
++
++#define INITIATORS_AREA_BL_X (WIDTH_EMIF_AREA)
++#define INITIATORS_AREA_BL_Y (MAX_HEIGHT)
++#define INITIATORS_AREA_TR_X (MAX_WIDTH)
++#define INITIATORS_AREA_TR_Y (MAX_HEIGHT - HEIGHT_EMIF_AREA)
++
++
++const char *string_list[TOTAL_Y_PARAMETERS] = {
++        "----DDR BANDWIDTH PLOT----",
++        "8 GBPS",
++        "6.4 ",
++        "4.8",
++        "3.2",
++        "1.6",
++        "0",
++        "EMIF Plot",
++        "test",
++        "EMIF1",
++        "test",
++        "EMIF2",
++        "TOP 6 INITIATORS",
++        "test",
++        "MPU",
++        "test",
++        "DSS",
++        "test",
++        "DSP",
++        "test",
++        "IVA",
++        "test",
++        "GPU",
++        "test",
++        "BB2D",
++};
++
+diff --git a/clients/time_bar_graph.c b/clients/time_bar_graph.c
+new file mode 100644
+index 0000000..9fa9c12
+--- /dev/null
++++ b/clients/time_bar_graph.c
+@@ -0,0 +1,515 @@
++/*
++ * Copyright Â© 2008 Kristian Høgsberg
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that copyright
++ * notice and this permission notice appear in supporting documentation, and
++ * that the name of the copyright holders not be used in advertising or
++ * publicity pertaining to distribution of the software without specific,
++ * written prior permission.  The copyright holders make no representations
++ * about the suitability of this software for any purpose.  It is provided "as
++ * is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
++ * OF THIS SOFTWARE.
++ */
++
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <stdint.h>
++#include <signal.h>
++#include <time.h>
++#include <math.h>
++#include <cairo.h>
++#include <sys/time.h>
++#include <pthread.h>
++#include <errno.h>
++#include <unistd.h>
++#include <sys/eventfd.h>
++#include <sys/epoll.h>
++
++#include <linux/input.h>
++#include <wayland-client.h>
++#include "window.h"
++#include "../shared/cairo-util.h"
++#include "time_bar_graph.h"
++
++//#define DEBUG 1
++#ifdef DEBUG 
++#define DBG(x...) printf(x)
++#else
++#define DBG(x...) // printf(x)
++#endif
++
++#define MAX_ITEMS        180
++#define MAX_TEXT_SIZE    128
++
++struct graph_dataset_point {
++      int next_index;
++      double y_values[MAX_ITEMS];
++};
++
++struct graph_data {
++      int dataset_size;
++      int first_index, last_index, num_elems;
++      uint64_t last_time;
++      struct graph_dataset_point dataset[1];
++};
++
++struct graph {
++      struct display *display;
++      struct window *window;
++      struct widget *widget;
++      int width, height;
++      struct time_graph_create_params params;
++      struct bar_graph_create_params bar_graph_params;
++      struct _y_config y_config_array[MAX_ITEMS];
++      struct _text_config text_config_array[MAX_ITEMS];
++
++      /* Bar graph parameters */
++      struct _bar_graph_y_config bar_graph_y_config_array[MAX_ITEMS];
++      struct _text_config bar_graph_text_config_array[MAX_ITEMS];
++
++      pthread_t thr;
++      int eventfd;
++      struct task task;
++      double x_scaling_factor;
++      pthread_mutex_t mtx;
++      double time_graph_y_values[MAX_ITEMS];
++      char text_values[MAX_ITEMS][MAX_TEXT_SIZE];
++
++      double bar_graph_y_values[MAX_ITEMS];
++      char bar_graph_text_values[MAX_ITEMS][MAX_TEXT_SIZE];
++
++      uint64_t time_now;
++      time_t start_time_tv_sec;
++      struct graph_data *data;
++};
++
++struct graph *global_graph=NULL;
++static void
++draw_stuff(struct graph *g, cairo_surface_t *surface)
++{
++      cairo_t *cr;
++      int i, j, n_elems;
++      double c_x, c_y, d_x, d_y;
++
++      cr = cairo_create(surface);
++      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
++      cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.5);
++      cairo_paint(cr);
++      cairo_select_font_face(cr, "mono",
++                      CAIRO_FONT_SLANT_NORMAL,
++                      CAIRO_FONT_WEIGHT_BOLD);
++      cairo_set_line_width (cr, 1.0);
++      cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
++      pthread_mutex_lock(&g->mtx);
++      for (j=0; g->data->num_elems > 0 && j<g->params.num_of_y_items; j++) {
++              n_elems = g->data->num_elems;
++              DBG("first_index: %d, last_index: %d\n", g->data->first_index, g->data->last_index);
++              if (g->y_config_array[j].fill_color.a != 0.0)
++                      cairo_move_to(cr, (double)g->params.draw_area.bottom_left.x, (double)g->params.draw_area.bottom_left.y);
++              c_x = (double)g->params.draw_area.bottom_left.x;
++              c_y = (double)g->params.draw_area.bottom_left.y;
++              d_x = 0;
++              i = g->data->first_index;
++              while (n_elems) {
++                      DBG("index: %d, x: %f, y: %f, next_index: %d\n", i, c_x,
++                              g->data->dataset[i].y_values[j], g->data->dataset[i].next_index);
++                      d_y = g->data->dataset[i].y_values[j] - c_y;
++                      c_y = g->data->dataset[i].y_values[j];
++                      c_x = c_x + d_x;
++                      if (g->y_config_array[j].fill_color.a == 0.0 && n_elems == g->data->num_elems) {
++                              cairo_move_to(cr, c_x, c_y);
++                      } else {
++                              cairo_curve_to(cr, c_x - (d_x * 0.75), c_y - (d_y * 0.92), c_x - (d_x * 0.25), c_y - (d_y * 0.08), c_x, c_y);
++                      }
++                      if (g->data->dataset[i].next_index > i) {
++                              d_x = (g->data->dataset[i].next_index - i);
++                      } else {
++                              d_x = (g->data->dataset_size + g->data->dataset[i].next_index - i);
++                      }
++                      i = g->data->dataset[i].next_index;
++                      n_elems--;
++              }
++              if (g->y_config_array[j].fill_color.a != 0.0) {
++                      cairo_line_to(cr, c_x, (double)g->params.draw_area.bottom_left.y);
++                      cairo_line_to(cr, (double)g->params.draw_area.bottom_left.x, (double)g->params.draw_area.bottom_left.y);
++                      cairo_close_path(cr);
++                      cairo_set_source_rgba(cr, g->y_config_array[j].fill_color.r, g->y_config_array[j].fill_color.g, 
++                                      g->y_config_array[j].fill_color.b, g->y_config_array[j].fill_color.a);
++                      cairo_fill_preserve(cr);
++              }
++              cairo_set_source_rgba(cr, g->y_config_array[j].line_color.r, g->y_config_array[j].line_color.g, 
++                      g->y_config_array[j].line_color.b, g->y_config_array[j].line_color.a);
++              cairo_stroke(cr);
++      }
++
++      for (j=0; j<g->params.num_of_text_items; j++) {
++              cairo_move_to(cr, (double)g->text_config_array[j].at.x, (double)g->text_config_array[j].at.y);
++              cairo_set_font_size(cr, g->text_config_array[j].fontsize);
++              cairo_set_source_rgba(cr, g->text_config_array[j].color.r, g->text_config_array[j].color.g, 
++                              g->text_config_array[j].color.b, g->text_config_array[j].color.a);
++              cairo_show_text(cr, g->text_values[j]);
++      }
++
++      
++      for (j=0; j<g->bar_graph_params.num_of_y_items; j++) {
++              cairo_move_to(cr, (double)g->bar_graph_params.y_config_array[j].region.bottom_left.x,
++                      (double)g->bar_graph_params.y_config_array[j].region.bottom_left.y);
++              c_y = (double)g->bar_graph_params.y_config_array[j].region.bottom_left.y -
++                  (g->bar_graph_y_values[j] * (double)(g->bar_graph_params.y_config_array[j].region.bottom_left.y -
++                      g->bar_graph_params.y_config_array[j].region.top_right.y));
++              cairo_line_to(cr, (double)g->bar_graph_params.y_config_array[j].region.bottom_left.x, c_y);
++              cairo_line_to(cr, (double)g->bar_graph_params.y_config_array[j].region.top_right.x, c_y);
++              cairo_line_to(cr, (double)g->bar_graph_params.y_config_array[j].region.top_right.x,
++                      (double)g->bar_graph_params.y_config_array[j].region.bottom_left.y);
++              cairo_line_to(cr, (double)g->bar_graph_params.y_config_array[j].region.bottom_left.x,
++                      (double)g->bar_graph_params.y_config_array[j].region.bottom_left.y);
++              cairo_close_path(cr);
++              cairo_set_source_rgba(cr, g->bar_graph_y_config_array[j].fill_color.r, g->bar_graph_y_config_array[j].fill_color.g, 
++                              g->bar_graph_y_config_array[j].fill_color.b, g->bar_graph_y_config_array[j].fill_color.a);
++              cairo_fill_preserve(cr);
++              cairo_set_source_rgba(cr, g->bar_graph_y_config_array[j].line_color.r, g->bar_graph_y_config_array[j].line_color.g, 
++                      g->bar_graph_y_config_array[j].line_color.b, g->bar_graph_y_config_array[j].line_color.a);
++              cairo_stroke(cr);
++      }
++      for (j=0; j<g->bar_graph_params.num_of_text_items; j++) {
++              cairo_move_to(cr, (double)g->bar_graph_text_config_array[j].at.x, (double)g->bar_graph_text_config_array[j].at.y);
++              cairo_set_font_size(cr, g->bar_graph_text_config_array[j].fontsize);
++              cairo_set_source_rgba(cr, g->bar_graph_text_config_array[j].color.r, g->bar_graph_text_config_array[j].color.g, 
++                              g->bar_graph_text_config_array[j].color.b, g->bar_graph_text_config_array[j].color.a);
++                cairo_save (cr);
++              //cairo_rotate(cr, 2*3.14*21/24);
++              cairo_show_text(cr, g->bar_graph_text_values[j]);
++              cairo_restore(cr);
++      }
++      pthread_mutex_unlock(&g->mtx);
++      cairo_destroy(cr);
++}
++
++static void
++resize_handler(struct widget *widget,
++             int32_t width, int32_t height, void *data)
++{
++      struct graph *g = data;
++
++      /* Dont resize me */
++      widget_set_size(g->widget, g->width, g->height);
++}
++
++static void
++redraw_handler(struct widget *widget, void *data)
++{
++      struct graph *g = data;
++      cairo_surface_t *surface;
++
++      surface = window_get_surface(g->window);
++      if (surface == NULL ||
++          cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
++              fprintf(stderr, "failed to create cairo egl surface\n");
++              return;
++      }
++
++      draw_stuff(g, surface);
++      cairo_surface_destroy(surface);
++}
++
++static void
++button_handler(struct widget *widget,
++             struct input *input, uint32_t time,
++             uint32_t button, enum wl_pointer_button_state state, void *data)
++{
++      struct graph *g = data;
++
++      switch (button) {
++      case BTN_LEFT:
++              if (state == WL_POINTER_BUTTON_STATE_PRESSED)
++                      window_move(g->window, input,
++                                  display_get_serial(g->display));
++              break;
++      case BTN_MIDDLE:
++              if (state == WL_POINTER_BUTTON_STATE_PRESSED)
++                      widget_schedule_redraw(widget);
++              break;
++      case BTN_RIGHT:
++              if (state == WL_POINTER_BUTTON_STATE_PRESSED)
++                      window_show_frame_menu(g->window, input, time);
++              break;
++      }
++}
++
++static void
++touch_down_handler(struct widget *widget, struct input *input, 
++                 uint32_t serial, uint32_t time, int32_t id, 
++                 float x, float y, void *data)
++{
++      struct graph *g = data;
++      window_move(g->window, input, display_get_serial(g->display));
++}
++
++static void task_run(struct task *task, uint32_t events)
++{
++      eventfd_t e;
++      struct graph *g = (struct graph *)(task->link.prev);
++      uint64_t time_diff;
++      int elems, tmp, incr, i;
++      double y;
++
++      eventfd_read(g->eventfd, &e);
++      if(e == 1) {
++              pthread_mutex_lock(&g->mtx);
++              /* Process new data */
++              DBG("time_now: %llu, last_time: %llu\n", g->time_now, g->data->last_time);
++              if (g->time_now > g->data->last_time) {
++                      time_diff = g->time_now - g->data->last_time;
++                      y = (double)time_diff * g->x_scaling_factor;
++                      incr = (int)y;
++                      DBG("incr: %d\n", incr);
++
++                      if (g->data->last_index >= g->data->first_index) elems = g->data->last_index - g->data->first_index + 1;
++                      else elems = g->data->dataset_size - g->data->first_index + g->data->last_index + 1;
++                      /* Move first index to make room for new element */
++                      while (g->data->dataset_size > 0 && (elems + incr) > g->data->dataset_size) {
++                              tmp = g->data->dataset[g->data->first_index].next_index - g->data->first_index;
++                              if (tmp < 0) tmp = g->data->dataset_size + tmp;
++                              g->data->first_index = g->data->dataset[g->data->first_index].next_index;
++                              elems -= tmp;
++                              g->data->num_elems--;
++                      }
++                      for (i=0; i<g->params.num_of_y_items; i++) {
++                              /* Scale Y */
++                              y = g->time_graph_y_values[i] * (double)(g->params.draw_area.bottom_left.y-g->params.draw_area.top_right.y);
++                              y = (double)g->params.draw_area.bottom_left.y - y;
++                              g->data->dataset[g->data->last_index].y_values[i] = y;
++                      }
++                      g->data->dataset[g->data->last_index].next_index = g->data->last_index + incr;
++                      if (g->data->dataset[g->data->last_index].next_index >= g->data->dataset_size) 
++                              g->data->dataset[g->data->last_index].next_index -= g->data->dataset_size;
++                      g->data->num_elems++;
++                      g->data->last_index = g->data->dataset[g->data->last_index].next_index;
++                      g->data->last_time = g->time_now;
++              }
++              pthread_mutex_unlock(&g->mtx);
++      }
++      widget_schedule_redraw(g->widget);
++      DBG("event task ran...\n");
++}
++
++void *time_graph_create(int argc, char *argv[], struct time_graph_create_params *cp)
++{
++      struct graph *g;
++      struct display *d;
++      int dataset_size;
++      struct timeval tv;
++
++      if (cp->num_of_y_items > MAX_ITEMS) return NULL;
++      if (cp->num_of_text_items > MAX_ITEMS) return NULL;
++
++      g = (struct graph*)malloc(sizeof(struct graph));
++      if (g == NULL) {
++              fprintf(stderr, "failed to allocate memory\n");
++              return NULL;
++      }
++      global_graph = g;
++      g->params = *cp;
++      if (cp->num_of_y_items)
++              memcpy(&g->y_config_array[0], cp->y_config_array,
++                      sizeof(struct _y_config) * cp->num_of_y_items);
++      if (cp->num_of_text_items)
++              memcpy(&g->text_config_array[0], cp->text_config_array,
++                      sizeof(struct _text_config) * cp->num_of_text_items);
++      d = display_create(&argc, argv);
++      if (d == NULL) {
++              fprintf(stderr, "failed to create display: %m\n");
++              return NULL;
++      }
++      g->display = d;
++      //g->bg_image = load_cairo_surface(cp->bg_image);
++      g->width = cp->width; //cairo_image_surface_get_width(g->bg_image);
++      g->height = cp->height; //cairo_image_surface_get_height(g->bg_image);
++      dataset_size = cp->draw_area.top_right.x - cp->draw_area.bottom_left.x;
++      g->data = (struct graph_data *)malloc(sizeof(struct graph_data) +
++              (dataset_size * sizeof(struct graph_dataset_point)));
++      if (!g->data) {
++              fprintf(stderr, "failed to allocate memory\n");
++              display_destroy(g->display);
++              //cairo_surface_destroy(g->bg_image);
++              free(g);
++              return NULL;
++      }
++      g->data->first_index = 0;
++      g->data->last_index = 0;
++      g->data->num_elems = 0;
++      g->data->dataset_size = dataset_size;
++      g->x_scaling_factor = (double)dataset_size / (double)cp->time_span;
++      g->window = window_create(d);
++      g->widget = window_add_widget(g->window, g);
++      window_set_title(g->window, cp->title);
++      widget_set_resize_handler(g->widget, resize_handler);
++      widget_set_redraw_handler(g->widget, redraw_handler);
++      widget_set_button_handler(g->widget, button_handler);
++      widget_set_default_cursor(g->widget, CURSOR_HAND1);
++      widget_set_touch_down_handler(g->widget, touch_down_handler);
++      window_schedule_resize(g->window, g->width, g->height);
++      g->eventfd = eventfd(0, 0);
++      g->task.run = task_run;
++      g->task.link.prev = (struct wl_list*)g;
++      g->task.link.next = NULL;
++      display_watch_fd(d, g->eventfd, EPOLLIN, &g->task);
++      pthread_mutex_init(&g->mtx, NULL);
++
++      if (0 != pthread_create(&g->thr, NULL, (void *(*)(void *))display_run, (void *)d)) {
++              fprintf(stderr, "pthread_create failed: %m\n");
++              widget_destroy(g->widget);
++              window_destroy(g->window);
++              display_destroy(g->display);
++              //cairo_surface_destroy(g->bg_image);
++              free(g->data);
++              close(g->eventfd);
++              free(g);
++              return NULL;
++      }
++      gettimeofday(&tv, NULL);
++      g->start_time_tv_sec = tv.tv_sec;
++      g->data->last_time = 0;
++      return (void*)g;
++}
++
++void move_graph(void *ctx, struct time_graph_create_params *cp)
++{
++      struct graph *g = ctx;
++      window_set_title(g->window, cp->title);
++}
++
++void time_graph_plot(void *ctx, double *y_values, const char *text_values[])
++{
++      struct timeval tv;
++      struct graph *g = ctx;
++      int i;
++      pthread_mutex_lock(&g->mtx);
++      gettimeofday(&tv, NULL);
++      g->time_now = ((tv.tv_sec - g->start_time_tv_sec) * 1000) + (tv.tv_usec / 1000);
++      memcpy(g->time_graph_y_values, y_values, g->params.num_of_y_items * sizeof(double));
++      for (i=0;i<g->params.num_of_text_items; i++) {
++              strncpy(g->text_values[i], text_values[i], MAX_TEXT_SIZE);
++              g->text_values[i][MAX_TEXT_SIZE-1] = '\0';
++      }
++      pthread_mutex_unlock(&g->mtx);
++      eventfd_write(g->eventfd, (eventfd_t)1);
++}
++
++void time_graph_destroy(void *ctx)
++{
++      struct graph *g = (struct graph *)ctx;
++      display_exit(g->display);
++      eventfd_write(g->eventfd, (eventfd_t)1);
++      pthread_join(g->thr, NULL);
++      widget_destroy(g->widget);
++      window_destroy(g->window);
++      display_destroy(g->display);
++      free(g->data);
++      close(g->eventfd);
++      free(g);
++      global_graph=NULL;
++}
++
++void util_get_cpu_usage(double *cpu_usage)
++{
++      static FILE *fp = NULL;
++      char buf[256];
++      uint64_t tot;
++      uint64_t u, n, s, i, w, x, y, z;
++      static uint64_t last_i = 0, last_total = 0;
++
++
++      if (!fp) {
++              if (!(fp = fopen("/proc/stat", "r")))
++                      fprintf(stderr, "Failed /proc/stat open: %s", strerror(errno));
++      }
++      if (fp) {
++              while (1) {
++                      rewind(fp);
++                      fflush(fp);
++                      if (!fgets(buf, sizeof(buf), fp)) {
++                              fprintf(stderr, "failed /proc/stat read\n");
++                      } else {
++                              sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
++                                              &u,
++                                              &n,
++                                              &s,
++                                              &i,
++                                              &w,
++                                              &x,
++                                              &y,
++                                              &z
++                                        );
++                              if (last_total == 0) {
++                                      last_total = u+n+s+i+w+x+y+z;
++                                      last_i = i;
++                                      usleep(100000);
++                              } else {
++                                      tot = u+n+s+i+w+x+y+z;
++                                      *cpu_usage = (1.0 - ((double)(i-last_i)/(double)(tot-last_total)));
++                                      last_i = i;
++                                      last_total = tot;
++                                      break;
++                              }
++                      }
++              }
++      }
++}
++
++void *bar_graph_create(int argc, char *argv[], struct bar_graph_create_params *cp)
++{
++      struct graph *g;
++      struct display *d;
++      struct timeval tv;
++
++      if (cp->num_of_y_items > MAX_ITEMS) return NULL;
++      if (cp->num_of_text_items > MAX_ITEMS) return NULL;
++
++      if (global_graph == NULL) {
++              fprintf(stderr, "graph not initialized invoke time_graph_create first\n");
++              return NULL;
++      }
++      g=global_graph;
++      g->bar_graph_params = *cp;
++      if (cp->num_of_y_items)
++              memcpy(&g->bar_graph_y_config_array[0], cp->y_config_array,
++                      sizeof(struct _bar_graph_y_config) * cp->num_of_y_items);
++      if (cp->num_of_text_items)
++              memcpy(&g->bar_graph_text_config_array[0], cp->text_config_array,
++                      sizeof(struct _text_config) * cp->num_of_text_items);
++
++      return g;
++}
++
++void bar_graph_plot(void *ctx, double *y_values, const char *text_values[])
++{
++      struct graph *g = ctx;
++      int i;
++      pthread_mutex_lock(&g->mtx);
++      memcpy(g->bar_graph_y_values, y_values, g->bar_graph_params.num_of_y_items * sizeof(double));
++      for (i=0;i<g->bar_graph_params.num_of_text_items; i++) {
++              strncpy(g->bar_graph_text_values[i], text_values[i], MAX_TEXT_SIZE);
++              g->bar_graph_text_values[i][MAX_TEXT_SIZE-1] = '\0';
++      }
++      pthread_mutex_unlock(&g->mtx);
++      //eventfd_write(g->eventfd, (eventfd_t)2);
++}
++
++void bar_graph_destroy(void *ctx)
++{
++      printf("Nothing to be done for this call\n");
++      return;
++}
++
+diff --git a/clients/time_bar_graph.h b/clients/time_bar_graph.h
+new file mode 100644
+index 0000000..97ac05a
+--- /dev/null
++++ b/clients/time_bar_graph.h
+@@ -0,0 +1,93 @@
++
++#ifndef _BAR_GRAPH_H_
++#define _BAR_GRAPH_H_
++
++#include <stdint.h>
++
++struct _rgba {
++      double r, g, b, a; // Values between 0 and 1
++};
++
++struct _coordinate {
++      uint32_t x, y; // Co-ordinates relative to top-left of the window
++};
++
++struct _rect {
++      struct _coordinate bottom_left, top_right;
++};
++
++struct _y_config {
++      struct _rgba line_color; // Line color
++      struct _rgba fill_color; // Fill color, 0 alpha => no fill
++};
++
++struct _text_config {
++      struct _rgba color; // Color for drawing the text, RGBA
++      struct _coordinate at; // where to draw the text
++      int fontsize;         // Font size
++};
++
++struct time_graph_create_params {
++      char *title;
++      //const char *bg_image;
++      uint32_t width;
++      uint32_t height;
++      struct _rect draw_area;
++      uint32_t time_span; // Amount of time the graph has to span in milliseconds
++      uint32_t num_of_y_items;
++      struct _y_config *y_config_array;
++      uint32_t num_of_text_items;
++      struct _text_config *text_config_array;
++};
++
++
++struct _bar_graph_y_config {
++      struct _rect region;     // Region for the bar graph
++      struct _rgba line_color; // Color for drawing the line, RGBA
++      struct _rgba fill_color; // Fill under the line with color RGBA, 0 => no fill
++};
++
++struct bar_graph_create_params {
++      char *title;
++      //const char *bg_image;
++      uint32_t num_of_y_items;
++      struct _bar_graph_y_config *y_config_array;
++      uint32_t num_of_text_items;
++      struct _text_config *text_config_array;
++};
++
++/* Creates a time graph using create parameters */
++void *bar_graph_create(int argc, char *argv[], struct bar_graph_create_params *cp);
++
++void move_graph(void *ctx, struct time_graph_create_params *cp);
++
++/* Plots a new set of y-values from the values in the array y_values. 
++   The number of values must be equal to "num_of_y_items" from create params 
++   y_values must be normalized between 0.0 to 1.0
++*/
++void bar_graph_plot(void *ctx, double *y_values, const char *text_values[]);
++
++/* Destroy the graph */
++void bar_graph_destroy(void *ctx);
++
++
++/* Creates a time graph using create parameters */
++void *time_graph_create(int argc, char *argv[], struct time_graph_create_params *cp);
++
++/* 
++ * Plots a new set of points from the values in the array y_values. 
++ * The number of values in the array y_values must be equal to "num_of_y_items"
++ * from create params 
++ * y_values must be normalized between 0.0 to 1.0
++
++ * The number of values in the array text_values must be equal to "num_of_text_items"
++ * from create params 
++*/
++void time_graph_plot(void *ctx, double *y_values, const char *text_values[]);
++
++/* Destroy the graph */
++void time_graph_destroy(void *ctx);
++
++void util_get_cpu_usage(double *cpu_usage);
++
++#endif /* _BAR_GRAPH_H_ */
+-- 
+1.9.1
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-Add-autolaunch-and-launch-rules-functional.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-Add-autolaunch-and-launch-rules-functional.patch
new file mode 100644 (file)
index 0000000..b6b32ae
--- /dev/null
@@ -0,0 +1,467 @@
+From 2e731255404e0efb0df1ede8d0b0a32ac011b420 Mon Sep 17 00:00:00 2001
+From: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Date: Sat, 16 Jul 2016 02:53:25 -0400
+Subject: [PATCH] ivi-shell: Add autolaunch and launch rules functionality
+
+Add ability to select application for autolaunch.
+Also launch rules settings are added.
+
+Signed-off-by: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Signed-off-by: Karthik Ramanan <a0393906@ti.com>
+---
+ ivi-shell/ivi-layout-controller-ti.c | 293 +++++++++++++++++++++++++++++++----
+ 1 file changed, 259 insertions(+), 34 deletions(-)
+
+diff --git a/ivi-shell/ivi-layout-controller-ti.c b/ivi-shell/ivi-layout-controller-ti.c
+index b7cf436..4a2d648 100644
+--- a/ivi-shell/ivi-layout-controller-ti.c
++++ b/ivi-shell/ivi-layout-controller-ti.c
+@@ -27,6 +27,9 @@
+ #include <string.h>
+ #include <assert.h>
++#include <fcntl.h>
++#include <unistd.h>
++
+ #include "ivi-layout-export.h"
+ #ifndef container_of
+@@ -56,13 +59,24 @@ if (__dl__ & debug_level) \
+ #define pr_wrn(...) __print_log(DL_WRN, "W: " __VA_ARGS__)
+ #define TRACE() __print_log(DL_DBG, "TR: %s - %d\n", __func__, __LINE__)
+-
+-#define WINDOWS_TITLE_HEIGHT 30
+ #define DEFAULT_SURFACE_ID_FOR_WL_SHELL_APP 0x80000000
+ /*****************************************************************************
+  *  structure, globals
+  ****************************************************************************/
++
++struct hmi_launch_rule {
++#define MAX_APP_NAME_LEN      64
++      char      app_name[MAX_APP_NAME_LEN];
++      int       screen_id;
++      int       order;
++      int       autofocus;
++      int       mode;
++      int32_t   src_rect[4];
++      int32_t   dest_rect[4];
++      int32_t   crop_rect[4];
++};
++
+ struct hmi_controller_layer {
+       struct ivi_layout_layer *ivilayer;
+       uint32_t id_layer;
+@@ -75,6 +89,7 @@ struct hmi_controller_layer {
+       struct wl_list link;
+       struct wl_list screen_link;
+       struct wl_list surfaces_list;
++      struct hmi_launch_rule *rule;
+ };
+ struct hmi_controller_surface {
+@@ -82,6 +97,7 @@ struct hmi_controller_surface {
+       void               *ivisurf;
+       struct wl_list     link;
+       struct wl_listener destroy_listener;
++      int                conf_num;
+ };
+ struct hmi_controller_screen {
+@@ -93,6 +109,8 @@ struct hmi_server_setting {
+       uint32_t    base_layer_id;
+       int32_t     panel_height;
+       char       *ivi_homescreen;
++      char       *homescreen_app;
++      struct wl_array rules;
+ };
+ struct hmi_controller {
+@@ -108,6 +126,7 @@ struct hmi_controller {
+       struct wl_listener                  destroy_listener;
+       struct wl_client                   *user_interface;
+       struct wl_list                      layers_list;
++
+ };
+ const struct ivi_controller_interface *ivi_controller_interface;
+@@ -143,6 +162,42 @@ mem_alloc(size_t size, char *file, int32_t line)
+ #define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
++static int
++get_process_name_by_pid(pid_t pid, char *name, int size)
++{
++      char proc_name[256] = "/proc/";
++      char n[512] = {0};
++      char *_n;
++
++      sprintf(&proc_name[strlen(proc_name)], "%d/exe", (int)pid);
++
++      if (!name
++          || access(proc_name, R_OK)
++          || (readlink(proc_name, n, sizeof(n)) <= 0)) {
++
++              return -1;
++      }
++
++      _n = strrchr(n, '/');
++      strncpy(name, _n ? (_n + 1) : n, size);
++
++      return 0;
++}
++
++static struct hmi_launch_rule
++*get_rule(struct wl_array *arr, const char *app_name)
++{
++      struct hmi_launch_rule *rule = NULL;
++
++      wl_array_for_each(rule, arr) {
++              if (!strcmp(app_name, rule->app_name))
++                      return rule;
++      }
++
++      return NULL;
++}
++
++
+ /**
+  * Internal method to create ivi_layer with hmi_controller_layer and
+  * add to a ivi_screen
+@@ -177,6 +232,42 @@ create_layer(struct ivi_layout_screen *iviscrn,
+ }
++static void
++register_layer_on_screen(struct hmi_controller *hmi_ctrl,
++                              int i,
++                              struct hmi_controller_layer *nlayer)
++{
++      unsigned cnt, j = 0;
++      struct hmi_controller_layer *layer = NULL;
++        struct ivi_layout_layer **layers;
++
++      if (nlayer->rule && nlayer->rule->order == 0) {
++              wl_list_insert(&hmi_ctrl->screens[i].layers_list, &nlayer->screen_link);
++      } else {
++              wl_list_for_each(layer, &hmi_ctrl->screens[i].layers_list, screen_link) {
++                      if (layer->rule && (layer->rule->order == 0))
++                              continue;
++                      else
++                              break;
++              }
++              wl_list_insert(layer->screen_link.prev, &nlayer->screen_link);
++      }
++
++      cnt = wl_list_length(&hmi_ctrl->screens[i].layers_list);
++
++      layers = calloc(cnt, sizeof(*layers));
++
++      wl_list_for_each_reverse(layer, &hmi_ctrl->screens[i].layers_list, screen_link) {
++              layers[j++] = layer->ivilayer;
++      }
++
++      ivi_controller_interface->screen_set_render_order(hmi_ctrl->screens[i].iviscrn, layers, cnt);
++
++      free(layers);
++
++      ivi_controller_interface->commit_changes();
++}
++
+ static struct hmi_controller_layer
+ *get_layer_for_surface(struct hmi_controller *hmi_ctrl
+                       , struct ivi_layout_surface *ivisurf
+@@ -188,6 +279,9 @@ static struct hmi_controller_layer
+       struct wl_client *client;
+       struct ivi_layout_screen *iviscrn  = NULL;
+       struct weston_output *output = NULL;
++      char proc_name[256];
++      struct hmi_launch_rule *rule;
++
+       pid_t pid;
+       uid_t uid;
+       gid_t gid;
+@@ -213,13 +307,21 @@ static struct hmi_controller_layer
+       pr_dbg("Existed layer for PID=%d was not found. Creating new\n", pid);
+-      for(;; i++) {
+-              if (wl_list_empty(&hmi_ctrl->screens[i].layers_list) ||
+-                              (i == (hmi_ctrl->screens_count - 1)))
+-                      break;
+-      };
++      get_process_name_by_pid(pid, proc_name, sizeof(proc_name));
+-      iviscrn = hmi_ctrl->screens[i].iviscrn;
++      rule = get_rule(&hmi_ctrl->hmi_setting->rules, proc_name);
++
++      if (rule && (rule->screen_id >= 0) && (rule->screen_id < hmi_ctrl->screens_count)) {
++              iviscrn = hmi_ctrl->screens[rule->screen_id].iviscrn;
++              i = rule->screen_id;
++      } else {
++              for(;; i++) {
++                      if (wl_list_empty(&hmi_ctrl->screens[i].layers_list) ||
++                                      (i == (hmi_ctrl->screens_count - 1)))
++                              break;
++              };
++              iviscrn = hmi_ctrl->screens[i].iviscrn;
++      }
+       layer = calloc(1, sizeof *layer);
+@@ -230,14 +332,16 @@ static struct hmi_controller_layer
+       wl_list_init(&layer->surfaces_list);
+       layer->width = output->width;
+-      layer->height = output->height + WINDOWS_TITLE_HEIGHT;
++      layer->height = output->height;
+       layer->id_layer = hmi_ctrl->hmi_setting->base_layer_id++;
+       layer->pid = pid;
++      layer->rule = rule;
+       create_layer(iviscrn, layer);
+       wl_list_insert(&hmi_ctrl->layers_list, &layer->link);
+-      wl_list_insert(&hmi_ctrl->screens[i].layers_list, &layer->screen_link);
++
++      register_layer_on_screen(hmi_ctrl, i, layer);
+       return layer;
+@@ -350,41 +454,77 @@ set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
+       struct hmi_controller_layer *hmi_ctrl_layer = NULL;
+       struct weston_surface *surface;
+       struct hmi_controller_surface *hmi_ctrl_surf = NULL;
++      int src_rect[4] = {0};
++      int dest_rect[4] = {0};
+       wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
+               wl_list_for_each(hmi_ctrl_surf, &hmi_ctrl_layer->surfaces_list, link) {
+                       if (hmi_ctrl_surf->ivisurf == ivisurf) {
+-                              pr_dbg("Surface was already configured. Skip add to list\n");
+                               goto found;
+                       }
+               }
+       }
+-      hmi_ctrl_layer = NULL;
++      return;
+ found:
+       surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
+-      if (surface) {
+-
+-              ivi_controller_interface->surface_set_source_rectangle(
+-                      ivisurf, 0, WINDOWS_TITLE_HEIGHT, surface->width,
+-                      surface->height);
+-
+-#if 0
+-              ivi_controller_interface->surface_set_destination_rectangle(
+-                      ivisurf, 0, 0, surface->width, surface->height);
+-#else
+-              if (hmi_ctrl_layer) {
+-                      ivi_controller_interface->surface_set_destination_rectangle(
+-                              ivisurf, 0, 0, hmi_ctrl_layer->width, hmi_ctrl_layer->height);
+-              } else {
+-                      ivi_controller_interface->surface_set_destination_rectangle(
+-                              ivisurf, 0, 0, surface->width, surface->height);
++      if (!surface)
++              return;
++
++      src_rect[2] = dest_rect[2] = surface->width;
++      src_rect[3] = dest_rect[3] = surface->height;
++
++      if (hmi_ctrl_layer && hmi_ctrl_layer->rule) {
++
++              if (hmi_ctrl_layer->rule->mode >= 0) {
++                      switch (hmi_ctrl_layer->rule->mode) {
++                      case 1:
++                              dest_rect[2] = hmi_ctrl_layer->width;
++                              dest_rect[3] = hmi_ctrl_layer->height;
++                      break;
++
++                      default:
++                              /* No changes, using requested size */
++                      break;
++                      }
++              }
++
++              if (hmi_ctrl_layer->rule->crop_rect[0] >= 0) {
++                      src_rect[0] += hmi_ctrl_layer->rule->crop_rect[0];
++                      src_rect[1] += hmi_ctrl_layer->rule->crop_rect[1];
++                      src_rect[2] -= (hmi_ctrl_layer->rule->crop_rect[0]
++                                       + hmi_ctrl_layer->rule->crop_rect[2]);
++                      src_rect[3] -= (hmi_ctrl_layer->rule->crop_rect[1]
++                                       + hmi_ctrl_layer->rule->crop_rect[3]);
++              }
++
++              if (hmi_ctrl_layer->rule->dest_rect[0] >= 0 ||
++                              hmi_ctrl_layer->rule->dest_rect[1] >= 0 ||
++                              hmi_ctrl_layer->rule->dest_rect[2] >= 0 ||
++                              hmi_ctrl_layer->rule->dest_rect[3] >= 0) {
++
++                      dest_rect[0] = hmi_ctrl_layer->rule->dest_rect[0];
++                      dest_rect[1] = hmi_ctrl_layer->rule->dest_rect[1];
++                      dest_rect[2] = hmi_ctrl_layer->rule->dest_rect[2] > 0 ?
++                                      hmi_ctrl_layer->rule->dest_rect[2] : dest_rect[2] ;
++                      dest_rect[3] = hmi_ctrl_layer->rule->dest_rect[3] > 0 ?
++                                      hmi_ctrl_layer->rule->dest_rect[3] : dest_rect[3] ;
+               }
+-#endif
+-              ivi_controller_interface->surface_set_visibility(ivisurf, true);
+-              ivi_controller_interface->commit_changes();
+       }
++
++      ivi_controller_interface->surface_set_source_rectangle(ivisurf
++                      , src_rect[0], src_rect[1]
++                      , src_rect[2], src_rect[3]);
++
++      ivi_controller_interface->surface_set_destination_rectangle(ivisurf
++                      , dest_rect[0], dest_rect[1]
++                      , dest_rect[2], dest_rect[3]);
++
++      ivi_controller_interface->surface_set_visibility(ivisurf, true);
++      ivi_controller_interface->commit_changes();
++
++      hmi_ctrl_surf->conf_num++;
+ }
+ static struct hmi_server_setting *
+@@ -393,6 +533,9 @@ hmi_server_setting_create(struct weston_compositor *ec)
+       struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
+       struct weston_config *config = ec->config;
+       struct weston_config_section *shell_section = NULL;
++      const char *name = NULL;
++
++      setting->panel_height = 30;
+       shell_section = weston_config_get_section(config, "ivi-shell",
+                                                 NULL, NULL);
+@@ -400,7 +543,78 @@ hmi_server_setting_create(struct weston_compositor *ec)
+       weston_config_section_get_uint(shell_section, "base-layer-id",
+                                      &setting->base_layer_id, 1000);
+-      setting->panel_height = 30;
++      if ((shell_section = weston_config_get_section(config, "ivi-autolaunch",
++                                                NULL, NULL))) {
++              weston_config_section_get_string(shell_section, "path",
++                                     &setting->homescreen_app, NULL);
++      }
++
++
++      wl_array_init(&setting->rules);
++
++      while (weston_config_next_section(config, &shell_section, &name)) {
++              int screen_id;
++              int order;
++              int mode;
++              int focus_on;
++              int crop_rect[4] = {-1, -1, -1, -1};
++              int src_rect[4]  = {-1, -1, -1, -1};
++              int dest_rect[4] = {-1, -1, -1, -1};
++              char *app_name;
++              char *buff;
++              struct hmi_launch_rule *rule = NULL;
++
++              if (0 != strcmp(name, "ivi-layout-rule"))
++                      continue;
++
++              if (0 != weston_config_section_get_string(shell_section, "application",
++                                                      &app_name, NULL))
++                      continue;
++
++              weston_config_section_get_int(shell_section, "order", &order, -1);
++              weston_config_section_get_int(shell_section, "mode", &mode, -1);
++              weston_config_section_get_int(shell_section, "focus_on", &focus_on, -1);
++              weston_config_section_get_int(shell_section, "screen", &screen_id, -1);
++
++              if (0 == weston_config_section_get_string(shell_section, "crop_rect",
++                                                      &buff, NULL)) {
++                      sscanf(buff, "%d,%d,%d,%d", crop_rect + 0,
++                                                  crop_rect + 1,
++                                                  crop_rect + 2,
++                                                  crop_rect + 3);
++              }
++
++              if (0 == weston_config_section_get_string(shell_section, "src_rect",
++                                                      &buff, NULL)) {
++                      sscanf(buff, "%d,%d,%d,%d", src_rect + 0,
++                                                  src_rect + 1,
++                                                  src_rect + 2,
++                                                  src_rect + 3);
++              }
++
++              if (0 == weston_config_section_get_string(shell_section, "dest_rect",
++                                                      &buff, NULL)) {
++                      sscanf(buff, "%d,%d,%d,%d", dest_rect + 0,
++                                                  dest_rect + 1,
++                                                  dest_rect + 2,
++                                                  dest_rect + 3);
++              }
++
++              rule = wl_array_add(&setting->rules, sizeof(*rule));
++
++              if (rule) {
++                      rule->screen_id = screen_id;
++                      rule->order     = order;
++                      rule->mode      = mode;
++                      rule->autofocus = focus_on;
++
++                      strncpy(rule->app_name, app_name, sizeof(rule->app_name));
++
++                      memcpy(rule->src_rect, src_rect, sizeof(rule->src_rect));
++                      memcpy(rule->dest_rect, dest_rect, sizeof(rule->dest_rect));
++                      memcpy(rule->crop_rect, crop_rect, sizeof(rule->crop_rect));
++              }
++      }
+       return setting;
+ }
+@@ -415,6 +629,15 @@ hmi_controller_destroy(struct wl_listener *listener, void *data)
+       free(hmi_ctrl);
+ }
++static void hmi_controller_launch_homescreen(struct hmi_controller *hmi_ctrl)
++{
++      if (hmi_ctrl->hmi_setting->homescreen_app) {
++              if(system(hmi_ctrl->hmi_setting->homescreen_app)) {
++                      ;
++              }
++      }
++}
++
+ static struct hmi_controller *
+ hmi_controller_create(struct weston_compositor *ec)
+ {
+@@ -429,9 +652,10 @@ hmi_controller_create(struct weston_compositor *ec)
+       ivi_controller_interface->get_screens(&screen_length, &pp_screen);
+-      for (i = screen_length; i-- ; j++) {
++      for (i = screen_length; i--;) {
+               iviscrn = pp_screen[i];
++              j = ivi_controller_interface->get_id_of_screen(iviscrn);
+               hmi_ctrl->screens[j].iviscrn = iviscrn;
+               wl_list_init(&hmi_ctrl->screens[i].layers_list);
+@@ -506,7 +730,6 @@ controller_module_init(struct weston_compositor *ec,
+ {
+       struct hmi_controller *hmi_ctrl = NULL;
+-
+       if (interface_version < sizeof(struct ivi_controller_interface)) {
+               weston_log("ivi-layout-controller-ti: version mismatch of controller interface");
+               return -1;
+@@ -528,5 +751,7 @@ controller_module_init(struct weston_compositor *ec,
+       weston_log("ivi-layout-controller-ti: Successfully started.");
++      hmi_controller_launch_homescreen(hmi_ctrl);
++
+       return 0;
+ }
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-Add-screenshooter-option.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-Add-screenshooter-option.patch
new file mode 100644 (file)
index 0000000..aa45011
--- /dev/null
@@ -0,0 +1,29 @@
+From 6189fb7936f469eab53db712f31dc8276075ff5e Mon Sep 17 00:00:00 2001
+From: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Date: Tue, 16 Aug 2016 23:47:23 -0400
+Subject: [PATCH] ivi-shell: Add screenshooter option
+
+Add ability to capture the screen.
+
+Signed-off-by: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Signed-off-by: Karthik Ramanan <a0393906@ti.com>
+---
+ ivi-shell/ivi-shell.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c
+index 1720705..5637d8e 100644
+--- a/ivi-shell/ivi-shell.c
++++ b/ivi-shell/ivi-shell.c
+@@ -456,6 +456,8 @@ module_init(struct weston_compositor *compositor,
+                                   argc, argv) < 0)
+               goto out_settings;
++      screenshooter_create(compositor);
++
+       retval = 0;
+ out_settings:
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-fix-TODO-which-expects-only-one-screen-in-.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-fix-TODO-which-expects-only-one-screen-in-.patch
new file mode 100644 (file)
index 0000000..d2af15e
--- /dev/null
@@ -0,0 +1,33 @@
+From 93ceff13467e7fb1bee38c0ab6f587f5f99cc594 Mon Sep 17 00:00:00 2001
+From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>
+Date: Wed, 25 Nov 2015 23:36:09 +0900
+Subject: [PATCH 1/7] ivi-shell: fix TODO which expects only one screen in the
+ system.
+
+It just return the first screen found in screen list.
+
+Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+---
+ ivi-shell/ivi-layout.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
+index a04076e..efc0da5 100644
+--- a/ivi-shell/ivi-layout.c
++++ b/ivi-shell/ivi-layout.c
+@@ -1484,9 +1484,8 @@ ivi_layout_get_screen_from_id(uint32_t id_screen)
+       struct ivi_layout_screen *iviscrn = NULL;
+       wl_list_for_each(iviscrn, &layout->screen_list, link) {
+-/* FIXME : select iviscrn from screen_list by id_screen */
+-              return iviscrn;
+-              break;
++              if (iviscrn->id_screen == id_screen)
++                      return iviscrn;
+       }
+       return NULL;
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-layer-controller-ti-Improve-functionality.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-layer-controller-ti-Improve-functionality.patch
new file mode 100644 (file)
index 0000000..7db4934
--- /dev/null
@@ -0,0 +1,326 @@
+From 70f5b755b00d5eab576ed897a8301367b0e367a6 Mon Sep 17 00:00:00 2001
+From: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Date: Sat, 16 Jul 2016 02:53:25 -0400
+Subject: [PATCH] ivi-shell: layer-controller-ti: Improve functionality
+
+Functionality improved:
+
+   * can launch multiple application on start
+   * handle keyboard focus:
+      - TAB-LEFTALT can be used for switch focus
+      - focus history;
+      - focus on new application.
+
+Signed-off-by: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Signed-off-by: Karthik Ramanan <a0393906@ti.com>
+---
+ ivi-shell/ivi-layout-controller-ti.c | 167 +++++++++++++++++++++++++++++++----
+ 1 file changed, 148 insertions(+), 19 deletions(-)
+
+diff --git a/ivi-shell/ivi-layout-controller-ti.c b/ivi-shell/ivi-layout-controller-ti.c
+index 4a2d648..9be51d1 100644
+--- a/ivi-shell/ivi-layout-controller-ti.c
++++ b/ivi-shell/ivi-layout-controller-ti.c
+@@ -30,6 +30,8 @@
+ #include <fcntl.h>
+ #include <unistd.h>
++#include <linux/input.h>
++
+ #include "ivi-layout-export.h"
+ #ifndef container_of
+@@ -85,6 +87,7 @@ struct hmi_controller_layer {
+       int32_t width;
+       int32_t height;
+       int32_t num_surfaces;
++      int32_t focus;
+       pid_t pid;
+       struct wl_list link;
+       struct wl_list screen_link;
+@@ -96,8 +99,10 @@ struct hmi_controller_surface {
+       void               *controller;
+       void               *ivisurf;
+       struct wl_list     link;
++      struct wl_list     focus_link;
+       struct wl_listener destroy_listener;
+       int                conf_num;
++      int                focus;
+ };
+ struct hmi_controller_screen {
+@@ -106,11 +111,12 @@ struct hmi_controller_screen {
+ };
+ struct hmi_server_setting {
+-      uint32_t    base_layer_id;
+-      int32_t     panel_height;
+-      char       *ivi_homescreen;
+-      char       *homescreen_app;
+-      struct wl_array rules;
++      uint32_t         base_layer_id;
++      int32_t          panel_height;
++      char            *ivi_homescreen;
++      char            *homescreen_app;
++      struct wl_array  autolaunch_apps;
++      struct wl_array  rules;
+ };
+ struct hmi_controller {
+@@ -126,6 +132,7 @@ struct hmi_controller {
+       struct wl_listener                  destroy_listener;
+       struct wl_client                   *user_interface;
+       struct wl_list                      layers_list;
++      struct wl_list                      focus_history_list;
+ };
+@@ -350,12 +357,59 @@ exit:
+ }
+ static void
++move_kbd_focus(struct hmi_controller_surface *ivisurf, struct hmi_controller *hmi_ctrl, bool history)
++{
++      struct hmi_controller_layer *layer;
++      struct hmi_controller_surface *surf;
++      struct weston_seat *seat;
++      struct weston_keyboard *keyboard;
++      struct weston_surface *surface;
++
++      wl_list_for_each(layer, &hmi_ctrl->layers_list, link) {
++              wl_list_for_each(surf, &layer->surfaces_list, link) {
++                      if (surf->focus) {
++                              surf->focus = 0;
++                              wl_list_insert(&hmi_ctrl->focus_history_list, &surf->focus_link);
++                              break;
++                      }
++              }
++      }
++
++      wl_list_for_each(seat, &hmi_ctrl->compositor->seat_list, link) {
++              if(!strcmp("default", seat->seat_name))
++                      break;
++      }
++
++      keyboard = weston_seat_get_keyboard(seat);
++
++      if (!keyboard)
++              return;
++
++      if (ivisurf) {
++              surface = ivi_controller_interface->surface_get_weston_surface(ivisurf->ivisurf);
++              weston_keyboard_set_focus(keyboard, surface);
++              ivisurf->focus = 1;
++
++              if (NULL != ivisurf->focus_link.next)
++                      wl_list_remove(&ivisurf->focus_link);
++
++      } else if (history && !wl_list_empty(&hmi_ctrl->focus_history_list)) {
++              struct hmi_controller_surface *s =
++                      wl_container_of(hmi_ctrl->focus_history_list.next, s, focus_link);
++              wl_list_remove(&s->focus_link);
++              surface = ivi_controller_interface->surface_get_weston_surface(s->ivisurf);
++              weston_keyboard_set_focus(keyboard, surface);
++              s->focus = 1;
++      }
++}
++
++static void
+ set_notification_create_surface(struct ivi_layout_surface *ivisurf,
+                               void *userdata)
+ {
+       struct hmi_controller *hmi_ctrl = userdata;
+-      struct hmi_controller_layer *hmi_ctrl_layer = NULL;
+-      struct hmi_controller_surface *hmi_ctrl_surf = NULL;
++      struct hmi_controller_layer *hmi_ctrl_layer;
++      struct hmi_controller_surface *hmi_ctrl_surf;
+       struct ivi_layout_layer *dest_layer;
+       struct weston_surface *surface;
+@@ -378,6 +432,7 @@ set_notification_create_surface(struct ivi_layout_surface *ivisurf,
+       hmi_ctrl_surf = calloc(1, sizeof(*hmi_ctrl_surf));
+       hmi_ctrl_surf->ivisurf = ivisurf;
+       wl_list_init(&hmi_ctrl_surf->link);
++      wl_list_init(&hmi_ctrl_surf->focus_link);
+       wl_list_insert(&hmi_ctrl_layer->surfaces_list, &hmi_ctrl_surf->link);
+@@ -419,6 +474,9 @@ remove:
+       wl_list_remove(&surf->link);
++      if (surf->focus)
++              move_kbd_focus(NULL, hmi_ctrl, true);
++
+       ivi_controller_interface->layer_remove_surface(dest_layer, ivisurf);
+       if (wl_list_empty(&hmi_ctrl_layer->surfaces_list)) {
+@@ -451,9 +509,10 @@ set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
+                                  void *userdata)
+ {
+       struct hmi_controller *hmi_ctrl = userdata;
+-      struct hmi_controller_layer *hmi_ctrl_layer = NULL;
++      struct hmi_controller_layer *hmi_ctrl_layer;
+       struct weston_surface *surface;
+-      struct hmi_controller_surface *hmi_ctrl_surf = NULL;
++      struct weston_seat *seat = NULL;
++      struct hmi_controller_surface *hmi_ctrl_surf;
+       int src_rect[4] = {0};
+       int dest_rect[4] = {0};
+@@ -511,6 +570,16 @@ found:
+                       dest_rect[3] = hmi_ctrl_layer->rule->dest_rect[3] > 0 ?
+                                       hmi_ctrl_layer->rule->dest_rect[3] : dest_rect[3] ;
+               }
++
++              if (hmi_ctrl_layer->rule->autofocus) {
++
++                      wl_list_for_each(seat, &hmi_ctrl->compositor->seat_list, link) {
++                              if(!strcmp("default", seat->seat_name))
++                                      break;
++                      }
++
++                      move_kbd_focus(hmi_ctrl_surf, hmi_ctrl, false);
++              }
+       }
+       ivi_controller_interface->surface_set_source_rectangle(ivisurf
+@@ -522,6 +591,7 @@ found:
+                       , dest_rect[2], dest_rect[3]);
+       ivi_controller_interface->surface_set_visibility(ivisurf, true);
++
+       ivi_controller_interface->commit_changes();
+       hmi_ctrl_surf->conf_num++;
+@@ -543,14 +613,9 @@ hmi_server_setting_create(struct weston_compositor *ec)
+       weston_config_section_get_uint(shell_section, "base-layer-id",
+                                      &setting->base_layer_id, 1000);
+-      if ((shell_section = weston_config_get_section(config, "ivi-autolaunch",
+-                                                NULL, NULL))) {
+-              weston_config_section_get_string(shell_section, "path",
+-                                     &setting->homescreen_app, NULL);
+-      }
+-
+-
+       wl_array_init(&setting->rules);
++      wl_array_init(&setting->autolaunch_apps);
++      wl_array_init(&setting->autolaunch_apps);
+       while (weston_config_next_section(config, &shell_section, &name)) {
+               int screen_id;
+@@ -564,6 +629,12 @@ hmi_server_setting_create(struct weston_compositor *ec)
+               char *buff;
+               struct hmi_launch_rule *rule = NULL;
++              if (!strcmp(name, "ivi-autolaunch")) {
++                      char **s = wl_array_add(&setting->autolaunch_apps, sizeof(*s));
++                      weston_config_section_get_string(shell_section, "path", s, NULL);
++                      continue;
++              }
++
+               if (0 != strcmp(name, "ivi-layout-rule"))
+                       continue;
+@@ -573,7 +644,7 @@ hmi_server_setting_create(struct weston_compositor *ec)
+               weston_config_section_get_int(shell_section, "order", &order, -1);
+               weston_config_section_get_int(shell_section, "mode", &mode, -1);
+-              weston_config_section_get_int(shell_section, "focus_on", &focus_on, -1);
++              weston_config_section_get_int(shell_section, "focus_on", &focus_on, 0);
+               weston_config_section_get_int(shell_section, "screen", &screen_id, -1);
+               if (0 == weston_config_section_get_string(shell_section, "crop_rect",
+@@ -631,8 +702,10 @@ hmi_controller_destroy(struct wl_listener *listener, void *data)
+ static void hmi_controller_launch_homescreen(struct hmi_controller *hmi_ctrl)
+ {
+-      if (hmi_ctrl->hmi_setting->homescreen_app) {
+-              if(system(hmi_ctrl->hmi_setting->homescreen_app)) {
++      char **app;
++
++      wl_array_for_each(app, &hmi_ctrl->hmi_setting->autolaunch_apps) {
++              if(system(*app)) {
+                       ;
+               }
+       }
+@@ -674,6 +747,7 @@ hmi_controller_create(struct weston_compositor *ec)
+                     &hmi_ctrl->destroy_listener);
+       wl_list_init(&hmi_ctrl->layers_list);
++      wl_list_init(&hmi_ctrl->focus_history_list);
+       free(pp_screen);
+       pp_screen = NULL;
+@@ -719,6 +793,57 @@ initialize(struct hmi_controller *hmi_ctrl)
+       return 1;
+ }
++static void
++switch_focus_bindings(struct weston_keyboard *keyboard, uint32_t time,
++               uint32_t key, void *data)
++{
++      struct hmi_controller *hmi_ctrl = data;
++      struct hmi_controller_layer *hmi_ctrl_layer, *next_l, *cycle_l = NULL;
++      struct hmi_controller_surface *hmi_ctrl_surf;
++      bool pp = false;
++
++      wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
++              wl_list_for_each(hmi_ctrl_surf, &hmi_ctrl_layer->surfaces_list, link) {
++                      if (hmi_ctrl_surf->focus) {
++                              goto ff;
++                      }
++              }
++      }
++
++      hmi_ctrl_surf = NULL;
++      pp = true;
++
++ff:
++      wl_list_for_each(next_l, &hmi_ctrl->layers_list, link) {
++
++              if (pp) {
++                      if (next_l->rule && next_l->rule->autofocus) {
++                              cycle_l = next_l;
++                              break;
++                      }
++              } else {
++                      if (next_l == hmi_ctrl_layer) {
++                              pp = true;
++                              continue;
++                      } else {
++                              if (next_l->rule && next_l->rule->autofocus) {
++                                      cycle_l = next_l;
++                                      break;
++                              }
++                      }
++              }
++      }
++
++      if (!cycle_l)
++              return;
++
++      move_kbd_focus(container_of(cycle_l->surfaces_list.next
++                                      , struct hmi_controller_surface
++                                      , link)
++                                              , hmi_ctrl, false);
++}
++
++
+ /*****************************************************************************
+  *  exported functions
+  ****************************************************************************/
+@@ -753,5 +878,9 @@ controller_module_init(struct weston_compositor *ec,
+       hmi_controller_launch_homescreen(hmi_ctrl);
++      weston_compositor_add_key_binding(ec, KEY_TAB , MODIFIER_ALT,
++                                              switch_focus_bindings, hmi_ctrl);
++      weston_install_debug_key_binding(ec, 0);
++
+       return 0;
+ }
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-udev-seat-restrict-udev-enumeration-to-card0.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-udev-seat-restrict-udev-enumeration-to-card0.patch
new file mode 100644 (file)
index 0000000..515f06c
--- /dev/null
@@ -0,0 +1,37 @@
+From e8e7a9f7dfa164a75fdbdca87622a2e13334478a Mon Sep 17 00:00:00 2001
+From: Anand Balagopalakrishnan <anandb@ti.com>
+Date: Sat, 23 Jan 2016 22:48:07 +0530
+Subject: [PATCH 1/1] udev-seat: restrict udev enumeration to card0
+
+In case of separate GPU and Display devices as found in embedded systems, we
+could have modeset node and render node controlled by different drivers.
+There is a distinct possibility that udev enumeration returns the DRM device
+corresponding to render node as the primary DRM device.
+
+Obviously, modeset operations cannot be done on the GPU DRM device.
+
+Restrict the udev enumeration to card0 and ensure that DRM device corresponding
+to display is returned as the primary DRM device.
+
+Upstream-Status: Pending
+
+Signed-off-by: Anand Balagopalakrishnan <anandb@ti.com>
+---
+ src/compositor-drm.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/compositor-drm.c b/src/compositor-drm.c
+index 6777bf8..59c2cc5 100644
+--- a/src/compositor-drm.c
++++ b/src/compositor-drm.c
+@@ -2827,7 +2827,7 @@ find_primary_gpu(struct drm_backend *b, const char *seat)
+
+       e = udev_enumerate_new(b->udev);
+       udev_enumerate_add_match_subsystem(e, "drm");
+-      udev_enumerate_add_match_sysname(e, "card[0-9]*");
++      udev_enumerate_add_match_sysname(e, "card0");
+
+       udev_enumerate_scan_devices(e);
+       drm_device = NULL;
+--
+1.7.9.5
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-weston1.9.0-Enabling-DRM-backend-with-multiple-displ.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-weston1.9.0-Enabling-DRM-backend-with-multiple-displ.patch
new file mode 100644 (file)
index 0000000..3efceb5
--- /dev/null
@@ -0,0 +1,60 @@
+From 15d9f155fdb3abffc348e81b1560702801994715 Mon Sep 17 00:00:00 2001
+From: Karthik Ramanan <a0393906@ti.com>
+Date: Mon, 11 Jan 2016 11:51:30 -0500
+Subject: [PATCH 1/2] weston1.9.0: Enabling DRM backend with multiple displays
+
+There are three main issues that this patch tries to address
+
+ 1. Black screen when running weston
+ 2. Support for multiple displays
+ 3. Handling missing VBlanks
+
+There is an issue with missing VBlanks for LCD and
+HDMI connectors which leads to display not getting refreshed.
+This patch can be considered as a workaround.
+
+Signed-off-by: Karthik Ramanan <a0393906@ti.com>
+---
+ src/compositor-drm.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/src/compositor-drm.c b/src/compositor-drm.c
+index 6777bf8..15ddba8 100644
+--- a/src/compositor-drm.c
++++ b/src/compositor-drm.c
+@@ -686,7 +686,7 @@ drm_output_repaint(struct weston_output *output_base,
+                       .request.sequence = 1,
+               };
+-              if ((!s->current && !s->next) ||
++              if ((!s->current && !s->next) &&
+                   !drm_sprite_crtc_supported(output, s->possible_crtcs))
+                       continue;
+@@ -847,6 +847,7 @@ page_flip_handler(int fd, unsigned int frame,
+ {
+       struct drm_output *output = (struct drm_output *) data;
+       struct timespec ts;
++      uint32_t bail;
+       uint32_t flags = PRESENTATION_FEEDBACK_KIND_VSYNC |
+                        PRESENTATION_FEEDBACK_KIND_HW_COMPLETION |
+                        PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
+@@ -864,9 +865,14 @@ page_flip_handler(int fd, unsigned int frame,
+       output->page_flip_pending = 0;
++      if(output->vblank_pending) {
++              weston_log("VBlank is pending for connector = %d, frame = %d\n", output->connector_id, frame);
++              bail = 1;
++      }
++
+       if (output->destroy_pending)
+               drm_output_destroy(&output->base);
+-      else if (!output->vblank_pending) {
++      else if (!output->vblank_pending || bail ) {
+               ts.tv_sec = sec;
+               ts.tv_nsec = usec * 1000;
+               weston_output_finish_frame(&output->base, &ts, flags);
+-- 
+1.9.1
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0002-Weston1.9.0-Allow-visual_id-to-be-0.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0002-Weston1.9.0-Allow-visual_id-to-be-0.patch
new file mode 100644 (file)
index 0000000..72d067f
--- /dev/null
@@ -0,0 +1,31 @@
+From 27cf7d0c260fa4754a021e9f6f92f83e2c99f5f4 Mon Sep 17 00:00:00 2001
+From: Eric Ruei <e-ruei1@ti.com>
+Date: Mon, 11 Jan 2016 11:59:19 -0500
+Subject: [PATCH 2/2] Weston1.9.0: Allow visual_id to be 0
+
+The inquiry of visual id from egl API eglGetConfigAttrib(EGL_NATIVE_VISUAL_ID)
+is an optional feature. The visual id will be set to 0 if this feature is
+not supported. Therefore, the return condition @function match_config_to_visual()
+should be (id == visual_id || id == 0) instead of (id == visual_id)
+
+Signed-off-by: Eric Ruei <e-ruei1@ti.com>
+---
+ src/gl-renderer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/gl-renderer.c b/src/gl-renderer.c
+index d7231f4..e1b925e 100644
+--- a/src/gl-renderer.c
++++ b/src/gl-renderer.c
+@@ -2194,7 +2194,7 @@ match_config_to_visual(EGLDisplay egl_display,
+                               &id))
+                       continue;
+-              if (id == visual_id)
++              if (id == visual_id || id == 0)
+                       return i;
+       }
+-- 
+1.9.1
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0002-ivi-shell-multi-screen-support-to-calcuration-of-a-m.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0002-ivi-shell-multi-screen-support-to-calcuration-of-a-m.patch
new file mode 100644 (file)
index 0000000..35835f0
--- /dev/null
@@ -0,0 +1,95 @@
+From 5c3c97aecadd59231e3b99a021080b019e1bbea4 Mon Sep 17 00:00:00 2001
+From: Nobuhiko Tanibata <nobuhiko_tanibata@xddp.denso.co.jp>
+Date: Wed, 9 Dec 2015 15:39:26 +0900
+Subject: [PATCH 2/7] ivi-shell: multi screen support to calcuration of a mask
+ of weston_surface.
+
+A weston_surface is transformed to multi screen coordinate, global
+coordinate by matrix:m now.
+
+Additionally, a mask needs to be calucated, taking account into,
+- multi screen coordination: a destination rectangle of layer in the
+  coordination is easily calcurated by adding weston_output.{x,y} in
+  simple. This is because there is no scaled and rotated transformation.
+- intersect inside of a screen the layer is assigned to. This is because
+  overlapped region of weston surface in another screen shall not be
+  displayed according to ivi use case.
+
+Signed-off-by: Nobuhiko Tanibata <nobuhiko_tanibata@xddp.denso.co.jp>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+---
+ ivi-shell/ivi-layout.c | 36 +++++++++++++++++++++++++++++++-----
+ 1 file changed, 31 insertions(+), 5 deletions(-)
+
+diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
+index efc0da5..c8ea270 100644
+--- a/ivi-shell/ivi-layout.c
++++ b/ivi-shell/ivi-layout.c
+@@ -665,15 +665,24 @@ calc_inverse_matrix_transform(const struct weston_matrix *matrix,
+ /**
+  * This computes the whole transformation matrix:m from surface-local
+- * coordinates to global coordinates. It is assumed that
+- * weston_view::geometry.{x,y} are zero.
++ * coordinates to multi screens coordinate, which is global coordinates.
++ * It is assumed that weston_view::geometry.{x,y} are zero.
+  *
+  * Additionally, this computes the mask on surface-local coordinates as a
+  * ivi_rectangle. This can be set to weston_view_set_mask.
+  *
+  * The mask is computed by following steps
+- * - destination rectangle of layer is inversed to surface-local cooodinates
+- *   by inversed matrix:m.
++ * - destination rectangle of layer is tansformed to multi screen coordinate,
++ *   global coordinates. This is done by adding weston_output.{x,y} in simple
++ *   because there is no scaled and rotated transformation.
++ * - destination rectangle of layer in multi screens coordinate needs to be
++ *   intersected inside of a screen the layer is assigned to. This is because
++ *   overlapped region of weston surface in another screen shall not be
++ *   displayed according to ivi use case.
++ * - destination rectangle of layer
++ *   - in multi screen coordinates,
++ *   - and intersected inside of an assigned screen,
++ *   is inversed to surface-local cooodinates by inversed matrix:m.
+  * - the area is intersected by intersected area between weston_surface and
+  *   source rectangle of ivi_surface.
+  */
+@@ -706,7 +715,17 @@ calc_surface_to_global_matrix_and_mask_to_weston_surface(
+                                                    lp->dest_y,
+                                                    lp->dest_width,
+                                                    lp->dest_height };
++      struct ivi_rectangle screen_dest_rect =    { output->x,
++                                                   output->y,
++                                                   output->width,
++                                                   output->height };
++      struct ivi_rectangle layer_dest_rect_in_global =
++                                                 { lp->dest_x + output->x,
++                                                   lp->dest_y + output->y,
++                                                   lp->dest_width,
++                                                   lp->dest_height };
+       struct ivi_rectangle surface_result;
++      struct ivi_rectangle layer_dest_rect_in_global_intersected;
+       /*
+        * the whole transformation matrix:m from surface-local
+@@ -729,9 +748,16 @@ calc_surface_to_global_matrix_and_mask_to_weston_surface(
+       ivi_rectangle_intersect(&surface_source_rect, &weston_surface_rect,
+                               &surface_result);
++      /*
++       * destination rectangle of layer in multi screens coordinate
++       * is intersected to avoid displaying outside of an assigned screen.
++       */
++      ivi_rectangle_intersect(&layer_dest_rect_in_global, &screen_dest_rect,
++                              &layer_dest_rect_in_global_intersected);
++
+       /* calc masking area of weston_surface from m */
+       calc_inverse_matrix_transform(m,
+-                                    &layer_dest_rect,
++                                    &layer_dest_rect_in_global_intersected,
+                                     &surface_result,
+                                     result);
+ }
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0003-Weston1.9.0-Fix-virtual-keyboard-display-issue-for-Q.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0003-Weston1.9.0-Fix-virtual-keyboard-display-issue-for-Q.patch
new file mode 100644 (file)
index 0000000..576b37e
--- /dev/null
@@ -0,0 +1,40 @@
+From 7d2f4a97306707fb29e743bf66a827e661aa5615 Mon Sep 17 00:00:00 2001
+From: Eric Ruei <e-ruei1@ti.com>
+Date: Tue, 23 Feb 2016 18:26:57 -0500
+Subject: [PATCH 3/3] Weston1.9.0: Fix virtual keyboard display issue for QT5
+ application
+
+The virtual keyboard does pop up as expected, however, it will never hide
+even when the application is terminated. This problem is due to the order
+of the text APIs( text_input_activate and test_input_show_input_panel) are
+invoked in QT5 and a potential bug of the API implementation. The virtual
+keyboard works as expected if the test_input_show_input_panel() is invoked
+prior to the test_input_activate() as most of the weston sample applications
+do. However, the problem will show up if that order is reversed and the reason
+why is that the current_panel is not set in this case and hence this panel
+cannot be hidden.
+
+It is required to set the current_panel to the text_input when the input_panel
+becomes visible at the first time.
+
+
+Signed-off-by: Eric Ruei <e-ruei1@ti.com>
+---
+ src/text-backend.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/text-backend.c b/src/text-backend.c
+index cd6c4d99..ba60949 100644
+--- a/src/text-backend.c
++++ b/src/text-backend.c
+@@ -338,6 +338,7 @@ text_input_show_input_panel(struct wl_client *client,
+                              text_input->surface);
+               wl_signal_emit(&ec->update_input_panel_signal,
+                              &text_input->cursor_rectangle);
++              text_input->manager->current_panel = text_input;
+       }
+ }
+-- 
+1.9.1
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0003-ivi-shell-avoid-update_prop-on-invisible-surfaces.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0003-ivi-shell-avoid-update_prop-on-invisible-surfaces.patch
new file mode 100644 (file)
index 0000000..2509713
--- /dev/null
@@ -0,0 +1,77 @@
+From 679cc873528ffb3fd94306a01dcf9d6ffa8eb120 Mon Sep 17 00:00:00 2001
+From: Nobuhiko Tanibata <nobuhiko_tanibata@xddp.denso.co.jp>
+Date: Wed, 9 Dec 2015 15:36:58 +0900
+Subject: [PATCH 3/7] ivi-shell: avoid update_prop() on invisible surfaces
+
+For multi screen support, ivi_layout_screen to be taken account into
+property change in commitChanges.
+
+Property change is now done in update_prop so to consider ivi_screen
+property for caluculating transform of weston surface, ivi_layout_screen
+ is added as a parameter of update_prop.
+
+However, update_prop of weston_view of a ivi_surface can not be done
+even if it is set on a screen. The propoerty change shall be done only
+when a visibility of ivi_surface or ivi_layer which contains the
+ivi_surface is ON. Such a condition shall be checked at commit_changes
+as well to avoid calling update_prop, which actually updates
+weston_views.
+
+Signed-off-by: Nobuhiko Tanibata <nobuhiko_tanibata@xddp.denso.co.jp>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+---
+ ivi-shell/ivi-layout.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
+index c8ea270..9dbebb3 100644
+--- a/ivi-shell/ivi-layout.c
++++ b/ivi-shell/ivi-layout.c
+@@ -763,16 +763,17 @@ calc_surface_to_global_matrix_and_mask_to_weston_surface(
+ }
+ static void
+-update_prop(struct ivi_layout_layer *ivilayer,
++update_prop(struct ivi_layout_screen  *iviscrn,
++          struct ivi_layout_layer *ivilayer,
+           struct ivi_layout_surface *ivisurf)
+ {
+       struct weston_view *tmpview;
+       struct ivi_rectangle r;
+       bool can_calc = true;
+-      if (!ivilayer->event_mask && !ivisurf->event_mask) {
++      /*In case of no prop change, this just returns*/
++      if (!ivilayer->event_mask && !ivisurf->event_mask)
+               return;
+-      }
+       update_opacity(ivilayer, ivisurf);
+@@ -828,8 +829,22 @@ commit_changes(struct ivi_layout *layout)
+       wl_list_for_each(iviscrn, &layout->screen_list, link) {
+               wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
++                      /*
++                       * If ivilayer is invisible, weston_view of ivisurf doesn't
++                       * need to be modified.
++                       */
++                      if (ivilayer->prop.visibility == false)
++                              continue;
++
+                       wl_list_for_each(ivisurf, &ivilayer->order.surface_list, order.link) {
+-                              update_prop(ivilayer, ivisurf);
++                              /*
++                               * If ivilayer is invisible, weston_view of ivisurf doesn't
++                               * need to be modified.
++                               */
++                              if (ivisurf->prop.visibility == false)
++                                      continue;
++
++                              update_prop(iviscrn, ivilayer, ivisurf);
+                       }
+               }
+       }
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0004-Weston1.9.0-Fix-touch-screen-crash-issue.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0004-Weston1.9.0-Fix-touch-screen-crash-issue.patch
new file mode 100644 (file)
index 0000000..c221d1c
--- /dev/null
@@ -0,0 +1,37 @@
+From 9a7c0e7b6ae9700069756b33d2ea726e58b552ed Mon Sep 17 00:00:00 2001
+From: Eric Ruei <e-ruei1@ti.com>
+Date: Wed, 16 Mar 2016 16:50:31 -0400
+Subject: [PATCH 4/4] Weston1.9.0: Fix touch screen crash issue
+
+Touch screen operation causes the weston to crash with segment fault sometimes.
+The crash occurs when the coordinate (x,y) passed to the weston input module
+is outside the view window, hence the weston compositor is not able to pick
+up a display view and there is no code to detect this condition at function
+notify_touch().
+
+
+Signed-off-by: Eric Ruei <e-ruei1@ti.com>
+---
+ src/input.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/input.c b/src/input.c
+index e230c83..fd8e53f 100644
+--- a/src/input.c
++++ b/src/input.c
+@@ -1566,6 +1566,12 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
+                * until all touch points are up again. */
+               if (touch->num_tp == 1) {
+                       ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
++                      if (!ev)
++                      {
++                              weston_log("notify_touch: weston_compositor_pick_view(%d, %d) failed to find a view!\n",
++                                                      wl_fixed_to_int(x), wl_fixed_to_int(y));
++                              return;
++                      }
+                       weston_touch_set_focus(touch, ev);
+               } else if (!touch->focus) {
+                       /* Unexpected condition: We have non-initial touch but
+-- 
+1.9.1
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0004-ivi-shell-fix-layout_layer.view_list-is-not-initiliz.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0004-ivi-shell-fix-layout_layer.view_list-is-not-initiliz.patch
new file mode 100644 (file)
index 0000000..ea5ef00
--- /dev/null
@@ -0,0 +1,44 @@
+From 2a07b287851c974d684aa152486a63062aadd219 Mon Sep 17 00:00:00 2001
+From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>
+Date: Wed, 25 Nov 2015 23:36:57 +0900
+Subject: [PATCH 4/7] ivi-shell: fix layout_layer.view_list is not initilized
+ per a screen.
+
+This is potential bug when it supports several screens. If view_list is
+initilized here, the views, which are set by the previous screen, are
+cleared. So View list shall be initilized in front of wl_list_for_each
+of all screens.
+
+Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+---
+ ivi-shell/ivi-layout.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
+index 9dbebb3..a7c5e22 100644
+--- a/ivi-shell/ivi-layout.c
++++ b/ivi-shell/ivi-layout.c
+@@ -1000,6 +1000,9 @@ commit_screen_list(struct ivi_layout *layout)
+       struct ivi_layout_layer   *ivilayer = NULL;
+       struct ivi_layout_layer   *next     = NULL;
+       struct ivi_layout_surface *ivisurf  = NULL;
++      
++      /* Clear view list of layout ivi_layer */
++      wl_list_init(&layout->layout_layer.view_list.link);
+       wl_list_for_each(iviscrn, &layout->screen_list, link) {
+               if (iviscrn->order.dirty) {
+@@ -1024,9 +1027,6 @@ commit_screen_list(struct ivi_layout *layout)
+                       iviscrn->order.dirty = 0;
+               }
+-              /* Clear view list of layout ivi_layer */
+-              wl_list_init(&layout->layout_layer.view_list.link);
+-
+               wl_list_for_each(ivilayer, &iviscrn->order.layer_list, order.link) {
+                       if (ivilayer->prop.visibility == false)
+                               continue;
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0005-ivi-shell-convert-from-screen-to-global-coordinates.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0005-ivi-shell-convert-from-screen-to-global-coordinates.patch
new file mode 100644 (file)
index 0000000..f22af13
--- /dev/null
@@ -0,0 +1,70 @@
+From 26c4fc86516626e2e463171e4016ccd851125342 Mon Sep 17 00:00:00 2001
+From: Nobuhiko Tanibata <nobuhiko_tanibata@xddp.denso.co.jp>
+Date: Wed, 9 Dec 2015 15:38:41 +0900
+Subject: [PATCH 5/7] ivi-shell: convert from screen to global coordinates
+
+In single screen, the coordinates of layer local coordinates are the
+same as global coordinates. However, to support multi screens, the
+layer-local coordinates shall be transformed to multi screen coordinates,
+which is global coordinates. The abosolute coordinates of a screen in global
+stored in (x,y) of output of its weston output so it shall be used to
+transform layer-local to global coordinates.
+
+Signed-off-by: Nobuhiko Tanibata <nobuhiko_tanibata@xddp.denso.co.jp>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+---
+ ivi-shell/ivi-layout.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
+index a7c5e22..c7506de 100644
+--- a/ivi-shell/ivi-layout.c
++++ b/ivi-shell/ivi-layout.c
+@@ -688,6 +688,7 @@ calc_inverse_matrix_transform(const struct weston_matrix *matrix,
+  */
+ static void
+ calc_surface_to_global_matrix_and_mask_to_weston_surface(
++      struct ivi_layout_screen  *iviscrn,
+       struct ivi_layout_layer *ivilayer,
+       struct ivi_layout_surface *ivisurf,
+       struct weston_matrix *m,
+@@ -695,6 +696,7 @@ calc_surface_to_global_matrix_and_mask_to_weston_surface(
+ {
+       const struct ivi_layout_surface_properties *sp = &ivisurf->prop;
+       const struct ivi_layout_layer_properties *lp = &ivilayer->prop;
++      struct weston_output *output = iviscrn->output;
+       struct ivi_rectangle weston_surface_rect = { 0,
+                                                    0,
+                                                    ivisurf->surface->width,
+@@ -732,7 +734,9 @@ calc_surface_to_global_matrix_and_mask_to_weston_surface(
+        * coordinates to global coordinates, which is computed by
+        * two steps,
+        * - surface-local coordinates to layer-local coordinates
+-       * - layer-local coordinates to global coordinates
++       * - layer-local coordinates to a single screen-local coordinates
++       * - a single screen-local coordinates to multi screen coordinates,
++         *   which is global coordinates.
+        */
+       calc_transformation_matrix(&surface_source_rect,
+                                  &surface_dest_rect,
+@@ -742,6 +746,8 @@ calc_surface_to_global_matrix_and_mask_to_weston_surface(
+                                  &layer_dest_rect,
+                                  lp->orientation, m);
++      weston_matrix_translate(m, output->x, output->y, 0.0f);
++
+       /* this intersected ivi_rectangle would be used for masking
+        * weston_surface
+        */
+@@ -798,7 +804,7 @@ update_prop(struct ivi_layout_screen  *iviscrn,
+               weston_matrix_init(&ivisurf->transform.matrix);
+               calc_surface_to_global_matrix_and_mask_to_weston_surface(
+-                      ivilayer, ivisurf, &ivisurf->transform.matrix, &r);
++                      iviscrn, ivilayer, ivisurf, &ivisurf->transform.matrix, &r);
+               if (tmpview != NULL) {
+                       weston_view_set_mask(tmpview, r.x, r.y, r.width, r.height);
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0006-ivi-shell-remove-a-code-which-expects-only-a-screen-.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0006-ivi-shell-remove-a-code-which-expects-only-a-screen-.patch
new file mode 100644 (file)
index 0000000..e0f5de3
--- /dev/null
@@ -0,0 +1,30 @@
+From ba9399549000bf581c5b309dd7a26ee818159d70 Mon Sep 17 00:00:00 2001
+From: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>
+Date: Wed, 25 Nov 2015 23:37:09 +0900
+Subject: [PATCH 6/7] ivi-shell: remove a code which expects only a screen in
+ the system.
+
+It breaks from wl_list_for_each of screens when the frist screen found.
+
+Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>
+Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
+---
+ ivi-shell/ivi-layout.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
+index c7506de..85cb457 100644
+--- a/ivi-shell/ivi-layout.c
++++ b/ivi-shell/ivi-layout.c
+@@ -1056,8 +1056,6 @@ commit_screen_list(struct ivi_layout *layout)
+                               ivisurf->surface->output = iviscrn->output;
+                       }
+               }
+-
+-              break;
+       }
+ }
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0007-ivi-shell-layout-Export-surface-destroy-callback.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0007-ivi-shell-layout-Export-surface-destroy-callback.patch
new file mode 100644 (file)
index 0000000..1fe7cf5
--- /dev/null
@@ -0,0 +1,60 @@
+From 9f47b84c94c71ef8bb1459c4c2b2759343432558 Mon Sep 17 00:00:00 2001
+From: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Date: Fri, 1 Jul 2016 22:38:43 -0400
+Subject: [PATCH 7/8] ivi-shell: layout: Export surface destroy callback
+
+[HACK]
+Some applications still using regular shell interface and
+thereby must be handled through weston native notifications.
+
+Only one and single notification callback accepted and it can be
+in external module.
+
+So we need to export call back for remove surface inside layout
+controlled.
+
+This is a obvious hack.
+
+Signed-off-by: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Signed-off-by: Karthik Ramanan <a0393906@ti.com>
+---
+ ivi-shell/ivi-layout-export.h | 7 +++++++
+ ivi-shell/ivi-layout.c        | 4 +++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h
+index 7f93c82..f5ea54e 100644
+--- a/ivi-shell/ivi-layout-export.h
++++ b/ivi-shell/ivi-layout-export.h
+@@ -823,6 +823,13 @@ struct ivi_controller_interface {
+        * \return id of ivi_screen
+        */
+       uint32_t (*get_id_of_screen)(struct ivi_layout_screen *iviscrn);
++
++      /**
++       * \brief HACK. Destroy surface.
++       *
++       */
++      void (*surface_destroy)(struct ivi_layout_surface *ivisurf);
++
+ };
+ #ifdef __cplusplus
+diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c
+index 85cb457..7d2daa1 100644
+--- a/ivi-shell/ivi-layout.c
++++ b/ivi-shell/ivi-layout.c
+@@ -3016,7 +3016,9 @@ static struct ivi_controller_interface ivi_controller_interface = {
+       /**
+        * screen controller interfaces part2
+        */
+-      .get_id_of_screen       = ivi_layout_get_id_of_screen
++      .get_id_of_screen       = ivi_layout_get_id_of_screen,
++
++      .surface_destroy        = ivi_layout_surface_destroy
+ };
+ int
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch
new file mode 100644 (file)
index 0000000..4e63c7a
--- /dev/null
@@ -0,0 +1,589 @@
+From c89c2d63db3cbe83fb1ddd983e4b0ffe87fab296 Mon Sep 17 00:00:00 2001
+From: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Date: Fri, 1 Jul 2016 00:28:50 -0400
+Subject: [PATCH 8/8] ivi-shell: Add simple IVI shell layout controller
+
+Simple IVI shell layout controller.
+Assign only one application to primary display.
+Second and rest application will go to secondary display if it's
+present.
+
+Signed-off-by: Volodymyr Riazantsev <volodymyr.riazantsev@globallogic.com>
+Signed-off-by: Karthik Ramanan <a0393906@ti.com>
+---
+ Makefile.am                          |  12 +-
+ ivi-shell/ivi-layout-controller-ti.c | 532 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 543 insertions(+), 1 deletion(-)
+ create mode 100644 ivi-shell/ivi-layout-controller-ti.c
+
+diff --git a/Makefile.am b/Makefile.am
+index 55aed6d..a9fe3c8 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -868,7 +868,8 @@ if ENABLE_IVI_SHELL
+ module_LTLIBRARIES +=                         \
+       $(ivi_shell)                            \
+-      $(hmi_controller)
++      $(hmi_controller)                       \
++      $(layout_controller)
+ ivi_shell = ivi-shell.la
+ ivi_shell_la_LDFLAGS = -module -avoid-version
+@@ -903,6 +904,15 @@ nodist_hmi_controller_la_SOURCES =                        \
+ BUILT_SOURCES += $(nodist_hmi_controller_la_SOURCES)
++layout_controller = layout-controller.la
++layout_controller_la_LDFLAGS = -module -avoid-version
++layout_controller_la_LIBADD = $(COMPOSITOR_LIBS) libshared.la
++layout_controller_la_CFLAGS = $(AM_CFLAGS) $(COMPOSITOR_CFLAGS)
++layout_controller_la_SOURCES =                                \
++      ivi-shell/ivi-layout-export.h                   \
++      ivi-shell/ivi-layout-controller-ti.c            \
++      shared/helpers.h
++
+ endif
+diff --git a/ivi-shell/ivi-layout-controller-ti.c b/ivi-shell/ivi-layout-controller-ti.c
+new file mode 100644
+index 0000000..b7cf436
+--- /dev/null
++++ b/ivi-shell/ivi-layout-controller-ti.c
+@@ -0,0 +1,532 @@
++/*
++ * Copyright (C) 2016 GlobalLogic Inc
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sublicense, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++ */
++
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++
++#include "ivi-layout-export.h"
++
++#ifndef container_of
++#define container_of(ptr, type, member) ({                              \
++        const __typeof__( ((type *)0)->member ) *__mptr = (ptr);        \
++        (type *)( (char *)__mptr - offsetof(type,member) );})
++#endif
++
++#ifndef BIT
++#define BIT(bit)      (1 << (bit))
++#endif
++
++#define __MODULE__ "layout-controller"
++#define DL_ERR        BIT(0)
++#define DL_WRN        BIT(1)
++#define DL_DBG        BIT(2)
++#define DL_ALL        (~0)
++
++static unsigned debug_level = DL_ALL;
++
++#define __print_log(__dl__, ... ) \
++if (__dl__ & debug_level) \
++              fprintf(__dl__ == DL_ERR ? stderr : stdout," ["__MODULE__"]:" __VA_ARGS__);
++
++#define pr_err(...) __print_log(DL_ERR, "E: " __VA_ARGS__)
++#define pr_dbg(...) __print_log(DL_DBG, "D: " __VA_ARGS__)
++#define pr_wrn(...) __print_log(DL_WRN, "W: " __VA_ARGS__)
++#define TRACE() __print_log(DL_DBG, "TR: %s - %d\n", __func__, __LINE__)
++
++
++#define WINDOWS_TITLE_HEIGHT 30
++#define DEFAULT_SURFACE_ID_FOR_WL_SHELL_APP 0x80000000
++
++/*****************************************************************************
++ *  structure, globals
++ ****************************************************************************/
++struct hmi_controller_layer {
++      struct ivi_layout_layer *ivilayer;
++      uint32_t id_layer;
++      int32_t x;
++      int32_t y;
++      int32_t width;
++      int32_t height;
++      int32_t num_surfaces;
++      pid_t pid;
++      struct wl_list link;
++      struct wl_list screen_link;
++      struct wl_list surfaces_list;
++};
++
++struct hmi_controller_surface {
++      void               *controller;
++      void               *ivisurf;
++      struct wl_list     link;
++      struct wl_listener destroy_listener;
++};
++
++struct hmi_controller_screen {
++      struct ivi_layout_screen *iviscrn;
++      struct wl_list layers_list;
++};
++
++struct hmi_server_setting {
++      uint32_t    base_layer_id;
++      int32_t     panel_height;
++      char       *ivi_homescreen;
++};
++
++struct hmi_controller {
++      int32_t                             current_layer;
++      int32_t                             current_screen;
++      int32_t                             screens_count;
++      int32_t                             workspace_count;
++
++      struct hmi_server_setting          *hmi_setting;
++      struct hmi_controller_screen        screens[4];
++      struct hmi_controller_layer         application_layer;
++      struct weston_compositor           *compositor;
++      struct wl_listener                  destroy_listener;
++      struct wl_client                   *user_interface;
++      struct wl_list                      layers_list;
++};
++
++const struct ivi_controller_interface *ivi_controller_interface;
++
++static void
++hmi_ctrl_surface_destroy(struct wl_listener *listener, void *data);
++
++int
++controller_module_init(struct weston_compositor *ec,
++                     int *argc, char *argv[],
++                     const struct ivi_controller_interface *interface,
++                     size_t interface_version);
++
++/*****************************************************************************
++ *  local functions
++ ****************************************************************************/
++static void *
++fail_on_null(void *p, size_t size, char *file, int32_t line)
++{
++      if (size && !p) {
++              weston_log("%s(%d) %zd: out of memory\n", file, line, size);
++              exit(EXIT_FAILURE);
++      }
++
++      return p;
++}
++
++static void *
++mem_alloc(size_t size, char *file, int32_t line)
++{
++      return fail_on_null(calloc(1, size), size, file, line);
++}
++
++#define MEM_ALLOC(s) mem_alloc((s),__FILE__,__LINE__)
++
++/**
++ * Internal method to create ivi_layer with hmi_controller_layer and
++ * add to a ivi_screen
++ */
++static void
++create_layer(struct ivi_layout_screen *iviscrn,
++           struct hmi_controller_layer *layer)
++{
++      int32_t ret = 0;
++
++      layer->ivilayer =
++              ivi_controller_interface->layer_create_with_dimension(layer->id_layer,
++                                                     layer->width,
++                                                     layer->height);
++      assert(layer->ivilayer != NULL);
++
++      ret = ivi_controller_interface->screen_add_layer(iviscrn, layer->ivilayer);
++
++      assert(!ret);
++
++      ret = ivi_controller_interface->layer_set_destination_rectangle(layer->ivilayer,
++                                                       layer->x, layer->y,
++                                                       layer->width,
++                                                       layer->height);
++      assert(!ret);
++
++      ret = ivi_controller_interface->layer_set_visibility(layer->ivilayer, true);
++
++      assert(!ret);
++
++      ivi_controller_interface->commit_changes();
++
++}
++
++static struct hmi_controller_layer
++*get_layer_for_surface(struct hmi_controller *hmi_ctrl
++                      , struct ivi_layout_surface *ivisurf
++                      , bool create)
++{
++      struct hmi_controller_layer *layer;
++      struct weston_surface *surface;
++      int32_t i = 0;
++      struct wl_client *client;
++      struct ivi_layout_screen *iviscrn  = NULL;
++      struct weston_output *output = NULL;
++      pid_t pid;
++      uid_t uid;
++      gid_t gid;
++
++      surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
++
++      if (!surface)
++              goto exit;
++
++      client = wl_resource_get_client(surface->resource);
++
++      wl_client_get_credentials(client, &pid, &uid, &gid);
++
++      wl_list_for_each(layer, &hmi_ctrl->layers_list, link) {
++              if (layer->pid == pid) {
++                      pr_dbg("Existed layer for PID=%d was found\n", pid);
++                      return layer;
++              }
++      }
++
++      if (!(create && hmi_ctrl->screens_count))
++              goto exit;
++
++      pr_dbg("Existed layer for PID=%d was not found. Creating new\n", pid);
++
++      for(;; i++) {
++              if (wl_list_empty(&hmi_ctrl->screens[i].layers_list) ||
++                              (i == (hmi_ctrl->screens_count - 1)))
++                      break;
++      };
++
++      iviscrn = hmi_ctrl->screens[i].iviscrn;
++
++      layer = calloc(1, sizeof *layer);
++
++      output = ivi_controller_interface->screen_get_output(iviscrn);
++
++      wl_list_init(&layer->link);
++      wl_list_init(&layer->screen_link);
++      wl_list_init(&layer->surfaces_list);
++
++      layer->width = output->width;
++      layer->height = output->height + WINDOWS_TITLE_HEIGHT;
++      layer->id_layer = hmi_ctrl->hmi_setting->base_layer_id++;
++      layer->pid = pid;
++
++      create_layer(iviscrn, layer);
++
++      wl_list_insert(&hmi_ctrl->layers_list, &layer->link);
++      wl_list_insert(&hmi_ctrl->screens[i].layers_list, &layer->screen_link);
++
++      return layer;
++
++exit:
++      return NULL;
++}
++
++static void
++set_notification_create_surface(struct ivi_layout_surface *ivisurf,
++                              void *userdata)
++{
++      struct hmi_controller *hmi_ctrl = userdata;
++      struct hmi_controller_layer *hmi_ctrl_layer = NULL;
++      struct hmi_controller_surface *hmi_ctrl_surf = NULL;
++      struct ivi_layout_layer *dest_layer;
++      struct weston_surface *surface;
++
++      wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
++              wl_list_for_each(hmi_ctrl_surf, &hmi_ctrl_layer->surfaces_list, link) {
++                      if (hmi_ctrl_surf->ivisurf == ivisurf) {
++                              pr_dbg("Surface was already configured. Skip add to list\n");
++                              return;
++                      }
++              }
++      }
++
++      pr_dbg("Surface create: add to list and get the layer\n");
++
++      hmi_ctrl_layer = get_layer_for_surface(hmi_ctrl, ivisurf, true);
++      dest_layer = hmi_ctrl_layer->ivilayer;
++
++      ivi_controller_interface->layer_add_surface(dest_layer, ivisurf);
++
++      hmi_ctrl_surf = calloc(1, sizeof(*hmi_ctrl_surf));
++      hmi_ctrl_surf->ivisurf = ivisurf;
++      wl_list_init(&hmi_ctrl_surf->link);
++      wl_list_insert(&hmi_ctrl_layer->surfaces_list, &hmi_ctrl_surf->link);
++
++
++      /*
++       * Set destroy signal for surface
++       * HACK: We trying to track surfaces were created by wl_shell_emulator
++       */
++      if (ivi_controller_interface->get_id_of_surface(ivisurf) >=
++                      DEFAULT_SURFACE_ID_FOR_WL_SHELL_APP) {
++              surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
++              hmi_ctrl_surf->destroy_listener.notify = hmi_ctrl_surface_destroy;
++              wl_signal_add(&surface->destroy_signal, &hmi_ctrl_surf->destroy_listener);
++              hmi_ctrl_surf->controller = userdata;
++      }
++}
++
++static void
++set_notification_remove_surface(struct ivi_layout_surface *ivisurf,
++                              void *userdata)
++{
++      struct hmi_controller *hmi_ctrl = userdata;
++      struct hmi_controller_layer *hmi_ctrl_layer = NULL;
++      struct hmi_controller_surface *surf = NULL;
++      struct ivi_layout_layer *dest_layer;
++
++      wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
++              wl_list_for_each(surf, &hmi_ctrl_layer->surfaces_list, link) {
++                      if (surf->ivisurf == ivisurf) {
++                              pr_dbg("Surface remove: surface was found\n");
++                              goto remove;
++                      }
++              }
++      }
++
++      goto exit;
++
++remove:
++      dest_layer = hmi_ctrl_layer->ivilayer;
++
++      wl_list_remove(&surf->link);
++
++      ivi_controller_interface->layer_remove_surface(dest_layer, ivisurf);
++
++      if (wl_list_empty(&hmi_ctrl_layer->surfaces_list)) {
++              wl_list_remove(&hmi_ctrl_layer->link);
++              wl_list_remove(&hmi_ctrl_layer->screen_link);
++              ivi_controller_interface->layer_destroy(dest_layer);
++              free(hmi_ctrl_layer);
++      }
++
++      free(surf);
++
++exit:
++      ivi_controller_interface->commit_changes();
++}
++
++static void
++hmi_ctrl_surface_destroy(struct wl_listener *listener, void *data)
++{
++      struct hmi_controller_surface *hmi_ctrl_surface =
++              container_of(listener, struct hmi_controller_surface,
++                      destroy_listener);
++
++      pr_dbg("Try to remove surface by direct notification\n");
++
++      ivi_controller_interface->surface_destroy(hmi_ctrl_surface->ivisurf);
++}
++
++static void
++set_notification_configure_surface(struct ivi_layout_surface *ivisurf,
++                                 void *userdata)
++{
++      struct hmi_controller *hmi_ctrl = userdata;
++      struct hmi_controller_layer *hmi_ctrl_layer = NULL;
++      struct weston_surface *surface;
++      struct hmi_controller_surface *hmi_ctrl_surf = NULL;
++
++      wl_list_for_each(hmi_ctrl_layer, &hmi_ctrl->layers_list, link) {
++              wl_list_for_each(hmi_ctrl_surf, &hmi_ctrl_layer->surfaces_list, link) {
++                      if (hmi_ctrl_surf->ivisurf == ivisurf) {
++                              pr_dbg("Surface was already configured. Skip add to list\n");
++                              goto found;
++                      }
++              }
++      }
++
++      hmi_ctrl_layer = NULL;
++found:
++      surface = ivi_controller_interface->surface_get_weston_surface(ivisurf);
++
++      if (surface) {
++
++              ivi_controller_interface->surface_set_source_rectangle(
++                      ivisurf, 0, WINDOWS_TITLE_HEIGHT, surface->width,
++                      surface->height);
++
++#if 0
++              ivi_controller_interface->surface_set_destination_rectangle(
++                      ivisurf, 0, 0, surface->width, surface->height);
++#else
++              if (hmi_ctrl_layer) {
++                      ivi_controller_interface->surface_set_destination_rectangle(
++                              ivisurf, 0, 0, hmi_ctrl_layer->width, hmi_ctrl_layer->height);
++              } else {
++                      ivi_controller_interface->surface_set_destination_rectangle(
++                              ivisurf, 0, 0, surface->width, surface->height);
++              }
++#endif
++              ivi_controller_interface->surface_set_visibility(ivisurf, true);
++              ivi_controller_interface->commit_changes();
++      }
++}
++
++static struct hmi_server_setting *
++hmi_server_setting_create(struct weston_compositor *ec)
++{
++      struct hmi_server_setting *setting = MEM_ALLOC(sizeof(*setting));
++      struct weston_config *config = ec->config;
++      struct weston_config_section *shell_section = NULL;
++
++      shell_section = weston_config_get_section(config, "ivi-shell",
++                                                NULL, NULL);
++
++      weston_config_section_get_uint(shell_section, "base-layer-id",
++                                     &setting->base_layer_id, 1000);
++
++      setting->panel_height = 30;
++
++      return setting;
++}
++
++static void
++hmi_controller_destroy(struct wl_listener *listener, void *data)
++{
++      struct hmi_controller *hmi_ctrl =
++              container_of(listener, struct hmi_controller, destroy_listener);
++
++      free(hmi_ctrl->hmi_setting);
++      free(hmi_ctrl);
++}
++
++static struct hmi_controller *
++hmi_controller_create(struct weston_compositor *ec)
++{
++      struct ivi_layout_screen **pp_screen = NULL;
++      struct ivi_layout_screen *iviscrn  = NULL;
++      int32_t screen_length  = 0;
++      struct hmi_controller *hmi_ctrl = MEM_ALLOC(sizeof(*hmi_ctrl));
++      int i, j = 0;
++
++      hmi_ctrl->hmi_setting = hmi_server_setting_create(ec);
++      hmi_ctrl->compositor = ec;
++
++      ivi_controller_interface->get_screens(&screen_length, &pp_screen);
++
++      for (i = screen_length; i-- ; j++) {
++
++              iviscrn = pp_screen[i];
++              hmi_ctrl->screens[j].iviscrn = iviscrn;
++              wl_list_init(&hmi_ctrl->screens[i].layers_list);
++
++              hmi_ctrl->screens_count++;
++      }
++
++      ivi_controller_interface->add_notification_create_surface(
++              set_notification_create_surface, hmi_ctrl);
++      ivi_controller_interface->add_notification_remove_surface(
++              set_notification_remove_surface, hmi_ctrl);
++      ivi_controller_interface->add_notification_configure_surface(
++              set_notification_configure_surface, hmi_ctrl);
++
++      hmi_ctrl->destroy_listener.notify = hmi_controller_destroy;
++      wl_signal_add(&hmi_ctrl->compositor->destroy_signal,
++                    &hmi_ctrl->destroy_listener);
++
++      wl_list_init(&hmi_ctrl->layers_list);
++
++      free(pp_screen);
++      pp_screen = NULL;
++
++      return hmi_ctrl;
++}
++
++WL_EXPORT const struct wl_interface ivi_hmi_controller_interface = {
++      "ivi_layout_controller", 1,
++      0, NULL,
++      0, NULL,
++};
++
++static void
++bind_hmi_controller(struct wl_client *client,
++                  void *data, uint32_t version, uint32_t id)
++{
++      struct hmi_controller *hmi_ctrl = data;
++
++      if (hmi_ctrl->user_interface != client) {
++              struct wl_resource *res = wl_client_get_object(client, 1);
++              wl_resource_post_error(res,
++                              WL_DISPLAY_ERROR_INVALID_OBJECT,
++                              "hmi-controller failed: permission denied");
++              return;
++      }
++
++      wl_resource_create(client, &ivi_hmi_controller_interface, 1, id);
++}
++
++static int32_t
++initialize(struct hmi_controller *hmi_ctrl)
++{
++      struct config_command {
++              char *key;
++              uint32_t *dest;
++      };
++
++      struct weston_config *config = hmi_ctrl->compositor->config;
++
++      weston_config_get_section(config, "ivi-shell", NULL, NULL);
++
++      return 1;
++}
++
++/*****************************************************************************
++ *  exported functions
++ ****************************************************************************/
++WL_EXPORT int
++controller_module_init(struct weston_compositor *ec,
++                     int *argc, char *argv[],
++                     const struct ivi_controller_interface *interface,
++                     size_t interface_version)
++{
++      struct hmi_controller *hmi_ctrl = NULL;
++
++
++      if (interface_version < sizeof(struct ivi_controller_interface)) {
++              weston_log("ivi-layout-controller-ti: version mismatch of controller interface");
++              return -1;
++      }
++
++      ivi_controller_interface = interface;
++
++      hmi_ctrl = hmi_controller_create(ec);
++
++      if (!initialize(hmi_ctrl)) {
++              return -1;
++      }
++
++      if (wl_global_create(ec->wl_display,
++                           &ivi_hmi_controller_interface, 1,
++                           hmi_ctrl, bind_hmi_controller) == NULL) {
++              return -1;
++      }
++
++      weston_log("ivi-layout-controller-ti: Successfully started.");
++
++      return 0;
++}
+-- 
+2.4.5
+
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/dra7xx-evm/weston.ini b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/dra7xx-evm/weston.ini
new file mode 100644 (file)
index 0000000..b5aa624
--- /dev/null
@@ -0,0 +1,59 @@
+[core]
+shell=ivi-shell.so
+
+[ivi-shell]
+ivi-module=layout-controller.so,wl-shell-emulator.so
+
+[ivi-autolaunch]
+path=/usr/AGL/CES2017/start_demo.sh
+
+#[ivi-layout-rule]
+## Application name
+#application=some_app
+## mode:0 - native size, 1 - full screen
+#mode=1
+## order:0 - always on top
+#order=0
+## screen id
+#screen=2
+## src_rect ignored
+#src_rect=1,2,3,4
+## destination
+#dest_rect=5,6,7,8
+## borders to crop (left,top,righ,bot)
+#crop_rect=9,10,11,12
+## ignored
+#focus_on=1
+
+[ivi-layout-rule]
+application=qmlscene
+screen=0
+mode=1
+crop_rect=5,30,10,10
+
+[ivi-layout-rule]
+application=soc-performance-monitor
+screen=1
+mode=0
+dest_rect=0,0,-1,-1
+
+[ivi-layout-rule]
+application=navi
+screen=0
+mode=0
+dest_rect=20,90,760,1100
+
+[ivi-layout-rule]
+application=soc-ddr-bw-visualizer
+screen=1
+mode=0
+dest_rect=400,0,-1,-1
+
+[ivi-layout-rule]
+application=gst-launch-1.0
+screen=1
+mode=1
+
+[output]
+name=Unknown-1
+transform=90
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/weston.service b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/weston.service
new file mode 100644 (file)
index 0000000..cec707d
--- /dev/null
@@ -0,0 +1,13 @@
+[Unit]
+Description=Weston reference Wayland compositor
+Conflicts=getty@tty1.service
+After=dbus.service rc.pvr.service
+
+[Service]
+ExecStart=/usr/bin/weston-launch -u root -- --backend=drm-backend.so --idle-time=4294967 --config=/etc/xdg/weston/weston.ini
+ExecStop=/usr/bin/killall -s KILL weston
+Restart=always
+Type=simple
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-agl-bsp/meta-ti/recipes-arago/weston/weston_1.9.0.bbappend b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston_1.9.0.bbappend
new file mode 100644 (file)
index 0000000..3c35ad8
--- /dev/null
@@ -0,0 +1,35 @@
+#inherit append-code-change
+# When configured for fbdev compositor, make it the default
+PACKAGECONFIG[fbdev] = "--enable-fbdev-compositor WESTON_NATIVE_BACKEND="fbdev-backend.so",--disable-fbdev-compositor,udev mtdev"
+PACKAGECONFIG[kms] = "--enable-drm-compositor,--disable-drm-compositor,drm udev libgbm mtdev"
+
+PR_append = ".agl_arago_16"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+RDEPENDS_${PN} += "weston-conf"
+
+SRC_URI += " \
+       file://0001-weston1.9.0-Enabling-DRM-backend-with-multiple-displ.patch \
+       file://0002-Weston1.9.0-Allow-visual_id-to-be-0.patch \
+       file://0003-Weston1.9.0-Fix-virtual-keyboard-display-issue-for-Q.patch \
+       file://0004-Weston1.9.0-Fix-touch-screen-crash-issue.patch \
+       file://0001-udev-seat-restrict-udev-enumeration-to-card0.patch \
+       file://0001-Add-soc-performance-monitor-utilites.patch \
+"
+
+RDEPENDS_${PN}_remove = "weston-conf"
+
+SRC_URI += " \
+      file://0001-ivi-shell-fix-TODO-which-expects-only-one-screen-in-.patch \
+      file://0002-ivi-shell-multi-screen-support-to-calcuration-of-a-m.patch \
+      file://0003-ivi-shell-avoid-update_prop-on-invisible-surfaces.patch    \
+      file://0004-ivi-shell-fix-layout_layer.view_list-is-not-initiliz.patch \
+      file://0005-ivi-shell-convert-from-screen-to-global-coordinates.patch  \
+      file://0006-ivi-shell-remove-a-code-which-expects-only-a-screen-.patch \
+      file://0007-ivi-shell-layout-Export-surface-destroy-callback.patch     \
+      file://0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch     \
+      file://0001-ivi-shell-Add-autolaunch-and-launch-rules-functional.patch \
+      file://0001-ivi-shell-layer-controller-ti-Improve-functionality.patch  \
+      file://0001-ivi-shell-Add-screenshooter-option.patch                   \
+      "