diff options
author | Karthik Ramanan <a0393906@ti.com> | 2016-11-18 13:17:53 +0530 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2016-11-22 16:32:17 +0000 |
commit | 534b92bdada2ec1920cdd9e16d2a5a4c286c4d1c (patch) | |
tree | 12100ff8ff479ff6651c4e6185e5e0b96ccd571c | |
parent | b678c686af5962c8ceec4517aa27992c9ba2d47b (diff) |
dra7xx-evm: weston: add changes for AGL home screen
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, 5859 insertions, 0 deletions
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 index 000000000..041e5abe1 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init.bbappend @@ -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 index 000000000..336e5af81 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init/init @@ -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 index 000000000..aed5d5f91 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston-init/weston-init/runWeston @@ -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 index 000000000..751a7cee9 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-Add-soc-performance-monitor-utilites.patch @@ -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(¶ms, 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 index 000000000..b6b32aef7 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-Add-autolaunch-and-launch-rules-functional.patch @@ -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 index 000000000..aa45011b9 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-Add-screenshooter-option.patch @@ -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 index 000000000..d2af15eca --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-fix-TODO-which-expects-only-one-screen-in-.patch @@ -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 index 000000000..7db49341e --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-ivi-shell-layer-controller-ti-Improve-functionality.patch @@ -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 index 000000000..515f06c47 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-udev-seat-restrict-udev-enumeration-to-card0.patch @@ -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 index 000000000..3efceb5db --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0001-weston1.9.0-Enabling-DRM-backend-with-multiple-displ.patch @@ -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 index 000000000..72d067fd9 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0002-Weston1.9.0-Allow-visual_id-to-be-0.patch @@ -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 index 000000000..35835f08c --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0002-ivi-shell-multi-screen-support-to-calcuration-of-a-m.patch @@ -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 index 000000000..576b37e15 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0003-Weston1.9.0-Fix-virtual-keyboard-display-issue-for-Q.patch @@ -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 index 000000000..2509713ba --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0003-ivi-shell-avoid-update_prop-on-invisible-surfaces.patch @@ -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 index 000000000..c221d1c5e --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0004-Weston1.9.0-Fix-touch-screen-crash-issue.patch @@ -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 index 000000000..ea5ef0024 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0004-ivi-shell-fix-layout_layer.view_list-is-not-initiliz.patch @@ -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 index 000000000..f22af13e6 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0005-ivi-shell-convert-from-screen-to-global-coordinates.patch @@ -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 index 000000000..e0f5de37d --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0006-ivi-shell-remove-a-code-which-expects-only-a-screen-.patch @@ -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 index 000000000..1fe7cf5aa --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0007-ivi-shell-layout-Export-surface-destroy-callback.patch @@ -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 index 000000000..4e63c7a0b --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/0008-ivi-shell-Add-simple-IVI-shell-layout-controller.patch @@ -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 index 000000000..b5aa624d1 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/dra7xx-evm/weston.ini @@ -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 index 000000000..cec707d56 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston/weston.service @@ -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 index 000000000..3c35ad821 --- /dev/null +++ b/meta-agl-bsp/meta-ti/recipes-arago/weston/weston_1.9.0.bbappend @@ -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 \ + " |