diff options
168 files changed, 22886 insertions, 0 deletions
diff --git a/meta-steppeeagle/.gitignore b/meta-steppeeagle/.gitignore new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/meta-steppeeagle/.gitignore diff --git a/meta-steppeeagle/COPYING.MIT b/meta-steppeeagle/COPYING.MIT new file mode 100644 index 00000000..89de3547 --- /dev/null +++ b/meta-steppeeagle/COPYING.MIT @@ -0,0 +1,17 @@ +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 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. diff --git a/meta-steppeeagle/binary/.gitignore b/meta-steppeeagle/binary/.gitignore new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/meta-steppeeagle/binary/.gitignore diff --git a/meta-steppeeagle/conf/layer.conf b/meta-steppeeagle/conf/layer.conf new file mode 100644 index 00000000..dab62903 --- /dev/null +++ b/meta-steppeeagle/conf/layer.conf @@ -0,0 +1,12 @@ +# We have a conf and classes directory, add to BBPATH +BBPATH .= ":${LAYERDIR}" + +# We have a recipes-* directories, add to BBFILES +BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ + ${LAYERDIR}/recipes-*/*/*.bbappend" + +BBFILE_COLLECTIONS += "steppeeagle" +BBFILE_PATTERN_steppeeagle = "^${LAYERDIR}/" +BBFILE_PRIORITY_steppeeagle = "6" + +LAYERDEPENDS_steppeeagle = "amd openembedded-layer" diff --git a/meta-steppeeagle/conf/machine/include/tune-steppeeagle.inc b/meta-steppeeagle/conf/machine/include/tune-steppeeagle.inc new file mode 100644 index 00000000..0c142a70 --- /dev/null +++ b/meta-steppeeagle/conf/machine/include/tune-steppeeagle.inc @@ -0,0 +1,18 @@ +DEFAULTTUNE ?= "dbft3b" + +require conf/machine/include/x86/arch-x86.inc +require conf/machine/include/x86-base.inc + + +# AMD DB-FT3b 64bit (SteppeEagle) +TUNEVALID[dbft3b] = "Enable AMD DB-FT3b (64 bit) specific processor optimizations" +TUNECONFLICTS[dbft3b] = "m32 mx32" +TUNE_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "dbft3b", "${X86ARCH64}", "" ,d)}" +TUNE_CCARGS .= "${@bb.utils.contains("TUNE_FEATURES", "dbft3b", " -march=btver2", "", d)}" + +# Extra tune selections +AVAILTUNES += "dbft3b" +TUNE_FEATURES_tune-dbft3b = "dbft3b" +BASE_LIB_tune-dbft3b = "lib64" +TUNE_PKGARCH_tune-dbft3b = "dbft3b" +PACKAGE_EXTRA_ARCHS_tune-dbft3b = "${TUNE_PKGARCH_tune-dbft3b}" diff --git a/meta-steppeeagle/conf/machine/steppeeagle.conf b/meta-steppeeagle/conf/machine/steppeeagle.conf new file mode 100644 index 00000000..96a80129 --- /dev/null +++ b/meta-steppeeagle/conf/machine/steppeeagle.conf @@ -0,0 +1,50 @@ +#@TYPE: Machine +#@NAME: steppeeagle + +#@DESCRIPTION: Machine configuration for steppeeagle systems + + +PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto" +PREFERRED_PROVIDER_jpeg ?= "jpeg" +PREFERRED_PROVIDER_jpeg-native ?= "jpeg-native" +PREFERRED_VERSION_linux-yocto = "3.12%" +PREFERRED_VERSION_mesa = "10.2.0+git%" +PREFERRED_VERSION_xf86-video-ati = "7.3.99+git%" +PREFERRED_VERSION_gstreamer1.0-omx = "git+git%" +PREFERRED_VERSION_llvm = "3.4" +PREFERRED_VERSION_libdrm = "2.4.53+git%" + +require conf/machine/include/tune-steppeeagle.inc + +MACHINE_FEATURES += "wifi efi pcbios" + +XSERVER_X86_RADEON = "xf86-video-ati \ + ${@base_contains('DISTRO_FEATURES', 'opengl', 'mesa-driver-radeon', '', d)} \ + " +XSERVER ?= "${XSERVER_X86_BASE} \ + ${XSERVER_X86_EXT} \ + ${XSERVER_X86_FBDEV} \ + ${XSERVER_X86_MODESETTING} \ + ${XSERVER_X86_RADEON} \ + " + +MACHINE_EXTRA_RRECOMMENDS += "v86d kernel-modules radeon-firmware alsa-utils" +MACHINE_EXTRA_RRECOMMENDS += "vdpauinfo grub" +MACHINE_EXTRA_RRECOMMENDS += "rtc-test watchdog-test spi-test smbus-test gpio-test" +MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "amd-gpio amd-spi amd-wdt amd-gpio-load amd-wdt-load" + +GLIBC_ADDONS = "nptl" + +EXTRA_OECONF_append_pn-matchbox-panel-2 = " --with-battery=acpi" + +# Setup a gettys on all serial ports +SERIAL_CONSOLES = "115200;ttyUSB0" + +# Make sure the kernel messages go to the VGA console and to the serial ports. +APPEND += "console=tty0 console=ttyUSB0,115200" + +RELEASE_IMAGE ?= "core-image-sato" + +APPEND += "radeon.dpm=1" + +SYSLINUX_LABELS = "boot" diff --git a/meta-steppeeagle/post-setup-environment b/meta-steppeeagle/post-setup-environment new file mode 100644 index 00000000..6807d5f6 --- /dev/null +++ b/meta-steppeeagle/post-setup-environment @@ -0,0 +1,4 @@ +if [ -e conf/local.conf ]; then + sed -i -e 's@\(CORE_IMAGE_EXTRA_INSTALL.*\)oprofile\(.*\)@\1\2@' \ + -e 's@\(EXTRA_IMAGE_FEATURES.*\)tools-profile\(.*\)@\1\2@' conf/local.conf +fi diff --git a/meta-steppeeagle/recipes-applications/gpio-test/files/gpio-test.c b/meta-steppeeagle/recipes-applications/gpio-test/files/gpio-test.c new file mode 100644 index 00000000..38c43276 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/gpio-test/files/gpio-test.c @@ -0,0 +1,575 @@ +/***************************************************************************** +* +* Copyright (c) 2014, Advanced Micro Devices, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Advanced Micro Devices, Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +***************************************************************************/ +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <signal.h> +#include <errno.h> +#include <string.h> + +#include <readline/readline.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/ioctl.h> + +#include "gpio-test.h" + +#define GPIO_APP_VERSION "0.1" +#define AMD_GPIO_NUM_PINS 184 +static int gpio_in_use[AMD_GPIO_NUM_PINS]; + +char *show_prompt(void) +{ + return "$ "; +} + +void sighandler(int sig) +{ + printf("\n%s", show_prompt()); +} + +void show_license(void) +{ + printf("/*****************************************************************************\n" + "*\n" + "* Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "* All rights reserved.\n" + "*\n" + "* Redistribution and use in source and binary forms, with or without\n" + "* modification, are permitted provided that the following conditions are met:\n" + "* * Redistributions of source code must retain the above copyright\n" + "* notice, this list of conditions and the following disclaimer.\n" + "* * Redistributions in binary form must reproduce the above copyright\n" + "* notice, this list of conditions and the following disclaimer in the\n" + "* documentation and/or other materials provided with the distribution.\n" + "* * Neither the name of Advanced Micro Devices, Inc. nor the names of\n" + "* its contributors may be used to endorse or promote products derived\n" + "* from this software without specific prior written permission.\n" + "*\n" + "* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n" + "* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n" + "* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n" + "* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY\n" + "* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n" + "* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n" + "* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" + "* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" + "* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n" + "* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "*\n" + "*\n" + "***************************************************************************/\n"); +} + +void print_usage() +{ + printf("\nCommands Supported ->\n"); + printf(" getgpiomode <gpio> : Gets the mode of GPIO pin\n"); + printf(" setgpiomode <gpio> <in/out/high/low> : Sets the mode of GPIO pin to input or output(high/low)\n"); + printf(" getgpiovalue <gpio> : Gets the value of GPIO pin\n"); + printf(" setgpiovalue <gpio> <high/low> : Sets the value of GPO pin to high or low\n"); + printf(" getnumgpio : Gets the number of GPIO pins supported\n"); + printf(" getgpiobase : Gets the number of first GPIO pin\n"); + printf(" getgpioname : Gets the name of GPIO driver currently in use\n"); + printf(" dmesg : Displays the kernel log messages related to GPIO\n"); + printf(" license : Displays the terms of LICENSE for this application\n"); + printf(" help : Displays help text\n"); + printf(" exit : Exits the application\n\n"); +} + +void parse_cmd(const char *cmdline) +{ + int fd; + + if (strncmp(cmdline, "help", 4) == 0) + print_usage(); + else if (strncmp(cmdline, "getnumgpio", 10) == 0) { + int fd; + char ngpio[3 + 1]; + + memset(ngpio, '\0', (3 + 1)); + fd = open("/sys/class/gpio/gpiochip0/ngpio", O_RDONLY); + if (fd < 0) { + printf("\nPlease make sure AMD GPIO driver is loaded\n"); + exit(EXIT_FAILURE); + } + + /* Value read from the file is ASCII text */ + if(read(fd, ngpio, 3) < 0) + perror("Cannot read number of GPIO pins"); + + printf("\nThe maximum number of GPIO pins supported is %d\n", atoi(ngpio)); + close(fd); + } else if (strncmp(cmdline, "getgpiobase", 11) == 0) { + int fd; + char gpiobase[3 + 1]; + + memset(gpiobase, '\0', (3 + 1)); + fd = open("/sys/class/gpio/gpiochip0/base", O_RDONLY); + if (fd < 0) { + printf("\nPlease make sure AMD GPIO driver is loaded\n"); + exit(EXIT_FAILURE); + } + + if(read(fd, gpiobase, 3) < 0) + perror("Cannot read GPIO base"); + + printf("\nGPIO pin numbering starts from %d\n", atoi(gpiobase)); + close(fd); + } else if (strncmp(cmdline, "getgpioname", 11) == 0) { + int fd; + char gpioname[10 + 1]; /* Max 10 characters + NULL character */ + + /* Zero initialize gpioname array */ + memset(gpioname, '\0', sizeof(gpioname)); + + fd = open("/sys/class/gpio/gpiochip0/label", O_RDONLY); + if (fd < 0) { + printf("\nPlease make sure AMD GPIO driver is loaded\n"); + exit(EXIT_FAILURE); + } + + if(read(fd, gpioname, 10) < 0) + perror("Cannot read GPIO driver name"); + + printf("\nGPIO driver loaded is %s\n", gpioname); + close(fd); + } else if (strncmp(cmdline, "getgpiovalue", 12) == 0) { + int fd; + int gpio; + const char *charp = cmdline; + char pathname[80]; + int ret = 0; + + /* Lets point to the end of first token */ + charp += strlen("getgpiovalue"); + /* Skip blank characters */ + while (*charp == ' ' || *charp == '\t' || *charp == '\n') + charp++; + + /* Now we should be pointing to the first 'digit' character */ + gpio = atoi(charp); + + fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd < 0) { + if (errno == EACCES) + printf("\nYou do not have correct permission, please run as root\n"); + else + perror("Eror opening /sys/class/gpio/export"); + + exit(EXIT_FAILURE); + } + + ret = write(fd, charp, strlen(charp)); + /* + * There can be two situations -> + * 1) The GPIO is being exported for the first time. + * 2) The GPIO is being exported again. + * In the first case, the write to file descriptor should + * succeed, and we should still fall into the if clause. + * + * In the second case, write will fail and errno will be + * set to EBUSY, since the GPIO pin is already exported. + * Rest all is error. + */ + if((ret >= 0) || ((ret < 0) && (errno == EBUSY))) { + /* Close the last file descriptor */ + close(fd); + + memset(pathname, '\0', sizeof(pathname)); + sprintf(pathname, "/sys/class/gpio/gpio%d/value", gpio); + + fd = open(pathname, O_RDONLY); + if (fd < 0) + perror("GPIO read error"); + else { + char value[1 + 1]; + + memset(value, '\0', 2); + ret = read(fd, value, 1); + if (ret < 0) + perror("Cannot read GPIO pin"); + + printf("\nGPIO pin %s is at \"%s\"\n", charp, + (strncmp(value, "1", 1) == 0) ? "high" : "low"); + + close(fd); + + /* + * Mark the GPIO as already exported, so that we can use + * unexport them during exit. + */ + gpio_in_use[gpio] = 1; + } + } else { + if (errno == EINVAL) + printf("\nInvalid GPIO number\n"); + else + perror("Error exporting GPIO number"); + + close(fd); + } + } else if (strncmp(cmdline, "getgpiomode", 11) == 0) { + int fd; + int gpio; + const char *charp = cmdline; + char pathname[80]; + int ret = 0; + + /* Lets point to the end of first token */ + charp += strlen("getgpiomode"); + /* Skip blank characters */ + while (*charp == ' ' || *charp == '\t' || *charp == '\n') + charp++; + + /* Now we should be pointing to the first 'digit' character */ + gpio = atoi(charp); + + fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd < 0) { + if (errno == EACCES) + printf("\nYou do not have correct permission, please run as root\n"); + else + perror("Eror opening /sys/class/gpio/export"); + + exit(EXIT_FAILURE); + } + + ret = write(fd, charp, strlen(charp)); + /* + * There can be two situations -> + * 1) The GPIO is being exported for the first time. + * 2) The GPIO is being exported again. + * In the first case, the write to file descriptor should + * succeed, and we should still fall into the if clause. + * + * In the second case, write will fail and errno will be + * set to EBUSY, since the GPIO pin is already exported. + * Rest all is error. + */ + if((ret >= 0) || ((ret < 0) && (errno == EBUSY))) { + FILE *fp; + + /* Close the last file descriptor */ + close(fd); + + memset(pathname, '\0', sizeof(pathname)); + sprintf(pathname, "/sys/class/gpio/gpio%d/direction", gpio); + + fp = fopen(pathname, "r"); + if (fp == NULL) + perror("GPIO read error"); + else { + char mode[3 + 1]; + int c, i = 0; + + memset(mode, '\0', (3 + 1)); + /* + * Since we do not exactly know whether the + * direction will be 'in' or 'out', we need to + * use fgetc() so that we read the input till + * we find terminating '\n', at which point + * we stop reading any further. + */ + while ((c = fgetc(fp)) != '\n') + mode[i++] = c; + + printf("\nGPIO pin %s is in \"%s\" mode\n", charp, + (strncmp(mode, "in", 2) == 0) ? "input" : "output"); + + fclose(fp); + + /* + * Mark the GPIO as already exported, so that we can use + * unexport them during exit. + */ + gpio_in_use[gpio] = 1; + } + } else { + if (errno == EINVAL) + printf("\nInvalid GPIO number\n"); + else + perror("Error exporting GPIO number"); + + close(fd); + } + } else if (strncmp(cmdline, "setgpiomode", 11) == 0) { + int fd; + const char *charp = cmdline; + int i = 0; + char gpio[3 + 1]; + int ngpio; + int ret; + + charp += strlen("setgpiomode"); + while (*charp == ' ' || *charp == '\t' || *charp == '\n') + charp++; + + memset(gpio, '\0', (3 + 1)); + /* + * We are at the start of string which contains the GPIO + * number. We look for the end of this string, copying + * byte by byte into array. We also make sure that we + * do not store more than 3 bytes into the array, since + * a GPIO can have a maximum value of 183, that is, not + * exceeding 3 characters. + */ + while (*charp != ' ' && *charp != '\t' && (i < 3)) { + gpio[i++] = *charp; + charp++; + } + + ngpio = atoi(gpio); + + fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd < 0) { + if (errno == EACCES) + printf("\nYou do not have correct permission, please run as root\n"); + else + perror("Eror opening /sys/class/gpio/export"); + + exit(EXIT_FAILURE); + } + + ret = write(fd, gpio, strlen(gpio)); + if((ret >= 0) || ((ret < 0) && (errno == EBUSY))) { + char pathname[80]; + + /* Close the last file descriptor */ + close(fd); + + memset(pathname, '\0', sizeof(pathname)); + sprintf(pathname, "/sys/class/gpio/gpio%d/direction", ngpio); + + fd = open(pathname, O_WRONLY); + if (fd < 0) + perror("GPIO read error"); + else { + char mode[4 + 1]; + + memset(mode, '\0', (4 + 1)); + + /* Lets skip the blanks till we find a character */ + while (*charp == ' ' || *charp == '\t') + charp++; + + i = 0; + /* + * Mode can be 'in', 'out', 'high' or 'low', + * again a maximum of 4 characters. + */ + while (*charp != ' ' && *charp != '\t' && (i < 4)) { + mode[i++] = *charp; + charp++; + } + + /* Sanity check */ + if ((strncmp(mode, "in", 2) == 0) || + (strncmp(mode, "out", 3) == 0) || + (strncmp(mode, "high", 4) == 0) || + (strncmp(mode, "low", 3) == 0)) { + /* Write mode into /sys/.../direction file */ + ret = write(fd, mode, strlen(mode)); + if (ret < 0) + perror("Error writing GPIO mode"); + } else + printf("\nInvalid GPIO mode, please try again\n"); + + close(fd); + + /* + * Mark the GPIO as exported, so that we can use + * unexport them during exit. + */ + gpio_in_use[ngpio] = 1; + } + } else { + if (errno == EINVAL) + printf("\nInvalid GPIO number\n"); + else + perror("Error exporting GPIO number"); + + close(fd); + } + } else if (strncmp(cmdline, "setgpiovalue", 12) == 0) { + int fd; + const char *charp = cmdline; + int i = 0; + char gpio[3 + 1]; + int ngpio; + int ret; + + charp += strlen("setgpiovalue"); + while (*charp == ' ' || *charp == '\t' || *charp == '\n') + charp++; + + memset(gpio, '\0', (3 + 1)); + /* + * We are at the start of string which contains the GPIO + * number. We look for the end of this string, copying + * byte by byte into array. We also make sure that we + * do not store more than 3 bytes into the array, since + * a GPIO can have a maximum value of 183, that is, not + * exceeding 3 characters. + */ + while (*charp != ' ' && *charp != '\t' && (i < 3)) { + gpio[i++] = *charp; + charp++; + } + + ngpio = atoi(gpio); + + fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd < 0) { + if (errno == EACCES) + printf("\nYou do not have correct permission, please run as root\n"); + else + perror("Eror opening /sys/class/gpio/export"); + + exit(EXIT_FAILURE); + } + + ret = write(fd, gpio, strlen(gpio)); + if((ret >= 0) || ((ret < 0) && (errno == EBUSY))) { + char pathname[80]; + + /* Close the last file descriptor */ + close(fd); + + memset(pathname, '\0', sizeof(pathname)); + sprintf(pathname, "/sys/class/gpio/gpio%d/value", ngpio); + + fd = open(pathname, O_WRONLY); + if (fd < 0) + perror("GPIO read error"); + else { + char value[1 + 1]; + + memset(value, '\0', (1 + 1)); + + /* Lets skip the blanks till we find a character */ + while (*charp == ' ' || *charp == '\t') + charp++; + + i = 0; + + if (strncmp(charp, "high", 4) == 0) + value[0] = '1'; + else if (strncmp(charp, "low", 3) == 0) + value[0] = '0'; + else { + printf("\nInvalid input, please try again...\n"); + goto out; + } + + /* Write mode into /sys/.../direction file */ + ret = write(fd, value, 1); + if (ret < 0) + perror("Error writing GPIO mode"); + +out: + close(fd); + + /* + * Mark the GPIO as exported, so that we can use + * unexport them during exit. + */ + gpio_in_use[ngpio] = 1; + } + } else { + if (errno == EINVAL) + printf("\nInvalid GPIO number\n"); + else + perror("Error exporting GPIO number"); + + close(fd); + } + } else if (strncmp(cmdline, "dmesg", 5) == 0) { + if (system("dmesg | grep GPIO") < 0) + perror("Error executing \'dmesg | grep GPIO\'"); + } else if (strncmp(cmdline, "license", 7) == 0) { + show_license(); + } else if (strncmp(cmdline, "exit", 4) == 0) { + int i; + int ret; + char gpio[3 + 1]; + + printf("\nExiting...\n"); + + /* We need to unexport all the GPIO pins exported earlier */ + for (i = 0; i < AMD_GPIO_NUM_PINS; i++) { + if (gpio_in_use[i]) { + int fd; + + fd = open("/sys/class/gpio/unexport", O_WRONLY); + if (fd < 0) { + printf("\nPlease make sure AMD GPIO driver is loaded\n"); + exit(EXIT_FAILURE); + } + memset(gpio, '\0', (3 + 1)); + snprintf(gpio, 4, "%d", i); + + ret = write(fd, gpio, strlen(gpio)); + if (ret < 0) + perror("Error writing to /sys/class/gpio/unexport"); + } + } + + exit(EXIT_SUCCESS); + } else { + printf("\nUnknown command\n"); + print_usage(); + } +} + +int main(void) +{ + char *cmdline= NULL; + + printf("GPIO sample application version: %s\n", GPIO_APP_VERSION); + printf("Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "This sample application comes with ABSOLUTELY NO WARRANTY;\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions; type `license' for details.\n\n"); + + /* Handler for Ctrl+C */ + signal(SIGINT, sighandler); + + while (1) { + cmdline = readline(show_prompt()); + parse_cmd(cmdline); + /* Free the memory malloc'ed by readline */ + free(cmdline); + } + + /* Should never reach here */ + return 0; +} diff --git a/meta-steppeeagle/recipes-applications/gpio-test/files/gpio-test.h b/meta-steppeeagle/recipes-applications/gpio-test/files/gpio-test.h new file mode 100644 index 00000000..af9c3b68 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/gpio-test/files/gpio-test.h @@ -0,0 +1,17 @@ +#ifndef _GPIO_TEST_H_ +#define _GPIO_TEST_H_ + + + +/* IOCTL numbers */ + +typedef struct { + int offset; + int value; +}debug_data; + +#define GPIO_TEST_IOC_MAGIC 'k' +#define GPIO_IOC_SWCTRLIN _IOW(GPIO_TEST_IOC_MAGIC, 1, debug_data) +#define GPIO_IOC_SWCTRLEN _IOW(GPIO_TEST_IOC_MAGIC, 2, debug_data) + +#endif /* _GPIO_TEST_H_ */ diff --git a/meta-steppeeagle/recipes-applications/gpio-test/gpio-test_1.0.bb b/meta-steppeeagle/recipes-applications/gpio-test/gpio-test_1.0.bb new file mode 100644 index 00000000..246a1c97 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/gpio-test/gpio-test_1.0.bb @@ -0,0 +1,27 @@ +DESCRIPTION = "Sample application for AMD GPIO driver" +SECTION = "applications" +LICENSE = "BSD" +DEPENDS = "readline" +LIC_FILES_CHKSUM = "file://gpio-test.c;md5=cd7d02789bf5b4795b385ad4f2938469 \ + file://gpio-test.h;md5=c7aaa743b172cf584032f9bfc5e85044 \ + " + +PR = "r1" +PV = "1.0" + +SRC_URI = "file://gpio-test.c \ + file://gpio-test.h \ + " + +TARGET_CC_ARCH += "${LDFLAGS}" + +S = "${WORKDIR}" + +do_compile() { + ${CC} gpio-test.c -o gpio-test -lreadline +} + +do_install() { + install -d ${D}${bindir} + install -m 0755 gpio-test ${D}${bindir} +} diff --git a/meta-steppeeagle/recipes-applications/rtc-test/files/rtc-test.c b/meta-steppeeagle/recipes-applications/rtc-test/files/rtc-test.c new file mode 100644 index 00000000..08088544 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/rtc-test/files/rtc-test.c @@ -0,0 +1,505 @@ +/***************************************************************************** +* +* Copyright (c) 2014, Advanced Micro Devices, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Advanced Micro Devices, Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +***************************************************************************/ +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <signal.h> +#include <errno.h> +#include <string.h> +#include <linux/rtc.h> + +#include <readline/readline.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/ioctl.h> + +#define RTC_APP_VERSION "0.1" +static const char *rtc = "/dev/rtc0"; +static int rtc_fd; +static int signal_recvd; +static volatile int loop; + +char *show_prompt(void) +{ + return "$ "; +} + +void sighandler(int sig) +{ + printf("\n%s", show_prompt()); +} + +void periodicinthandler(int sig) +{ + int ret; + + fprintf(stderr, "\nAborting...\n"); + fflush(stderr); + + loop = 0; + + /* Turn off periodic interrupts */ + ret = ioctl(rtc_fd, RTC_PIE_OFF, 0); + if (ret == -1) + perror("RTC_PIE_OFF ioctl"); + + /* Restore original handler for SIGINT */ + signal(SIGINT, sighandler); +} + +void updateinthandler(int sig) +{ + int ret; + + fprintf(stderr, "\nAborting...\n"); + fflush(stderr); + + loop = 0; + + /* Turn off update interrupt */ + ret = ioctl(rtc_fd, RTC_UIE_OFF, 0); + if (ret == -1) + perror("RTC_UIE_OFF ioctl"); + + /* Restore original handler for SIGINT */ + signal(SIGINT, sighandler); +} + +void alarminthandler(int sig) +{ + struct rtc_wkalrm rtc_wakealarm; + int ret; + + signal_recvd = 1; + + ret = ioctl(rtc_fd, RTC_WKALM_RD, &rtc_wakealarm); + if (ret == -1) { + perror("RTC_WKALM_RD ioctl"); + return; + } + + /* disable alarm and set pending to 0 */ + rtc_wakealarm.enabled = 0; + rtc_wakealarm.pending = 0; + + ret = ioctl(rtc_fd, RTC_WKALM_SET, &rtc_wakealarm); + if (ret == -1) { + perror("RTC_WKALM_SET ioctl"); + return; + } + + /* Restore original handler for SIGINT */ + signal(SIGINT, sighandler); +} + +void show_license(void) +{ + printf("/*****************************************************************************\n" + "*\n" + "* Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "* All rights reserved.\n" + "*\n" + "* Redistribution and use in source and binary forms, with or without\n" + "* modification, are permitted provided that the following conditions are met:\n" + "* * Redistributions of source code must retain the above copyright\n" + "* notice, this list of conditions and the following disclaimer.\n" + "* * Redistributions in binary form must reproduce the above copyright\n" + "* notice, this list of conditions and the following disclaimer in the\n" + "* documentation and/or other materials provided with the distribution.\n" + "* * Neither the name of Advanced Micro Devices, Inc. nor the names of\n" + "* its contributors may be used to endorse or promote products derived\n" + "* from this software without specific prior written permission.\n" + "*\n" + "* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n" + "* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n" + "* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n" + "* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY\n" + "* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n" + "* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n" + "* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" + "* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" + "* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n" + "* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "*\n" + "*\n" + "***************************************************************************/\n"); +} + +void print_usage(void) +{ + printf("\nCommands Supported ->\n"); + printf(" updateinton : Turns on update interrupt\n"); + printf(" updateintoff : Turns off update interrupt\n"); + printf(" getrtctime : Reads the current RTC time\n"); + printf(" setrtctime <date>, <time> : Sets RTC date and time. Both date and time are mandatory\n"); + printf(" getwakealarm : Reads the current alarm setting\n"); + printf(" setwakealarm <date>, <time> : Sets the alarm date and time. Both date and time are mandatory\n"); + printf(" wakealarmoff : Turn off wakeup alarm set previously\n"); + printf(" getperiodicrate : Reads the current periodic interrupt rate\n"); + printf(" setperiodicrate <rate> : Sets the periodic interrupt rate\n"); + printf(" : The rate can take values from 2 to 8192 in steps of " + "power of 2\n"); + printf(" : 2, 4, 8, ..., 8192\n"); + printf(" periodicinton : Turns on periodic interrupt\n"); + printf(" periodicintoff : Turns off periodic interrupt\n"); + printf(" license : Displays the terms of LICENSE for this application\n"); + printf(" help : Displays help text\n"); + printf(" exit : Exits the application\n\n"); +} + +void parse_cmd(const char *cmdline) +{ + int ret, irqcount = 0; + unsigned long data; + struct rtc_time rtc_time; + struct rtc_wkalrm rtc_wakealarm; + + if (strncmp(cmdline, "help", 4) == 0) + print_usage(); + else if (strncmp(cmdline, "updateinton", 11) == 0) { + int i; + + ret = ioctl(rtc_fd, RTC_UIE_ON, 0); + if (ret == -1) { + if (errno == ENOTTY) + fprintf(stderr, "\n..Update interrupt not supported.\n"); + + perror("RTC_UIE_ON ioctl"); + return; + } + + fprintf(stderr, "Counting update interrupts by reading %s...Press Ctrl+C to abort\n", rtc); + fflush(stderr); + + /* Set default handler for SIGINT */ + signal(SIGINT, updateinthandler); + + i = loop = 1; + while (loop) { + struct timeval tv = {5, 0}; + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(rtc_fd, &readfds); + + ret = select(rtc_fd + 1, &readfds, NULL, NULL, &tv); + if (ret == -1) { + if (errno != EINTR) + perror("select"); + + /* Break the loop */ + loop = 0; + } else { + /* Non blocking read */ + ret = read(rtc_fd, &data, sizeof(unsigned long)); + if (ret == -1) { + perror("read"); + loop = 0; + } else { + fprintf(stderr, " %d", i++); + irqcount++; + } + } + } + + /* Turn off update interrupt */ + ret = ioctl(rtc_fd, RTC_UIE_OFF, 0); + if (ret == -1) + perror("RTC_UIE_OFF ioctl"); + } else if (strncmp(cmdline, "updateintoff", 12) == 0) { + fprintf(stderr, "Turning update interrupt off\n"); + fflush(stderr); + + ret = ioctl(rtc_fd, RTC_UIE_OFF, 0); + if (ret == -1) + perror("RTC_UIE_OFF ioctl"); + } else if (strncmp(cmdline, "getrtctime", 10) == 0) { + ret = ioctl(rtc_fd, RTC_RD_TIME, &rtc_time); + if (ret == -1) + perror("RTC_RD_TIME ioctl"); + else + fprintf(stderr, "\nCurrent RTC date and time is %02d/%02d/%04d, %02d:%02d:%02d\n", + rtc_time.tm_mon + 1, rtc_time.tm_mday, rtc_time.tm_year + 1900, + rtc_time.tm_hour, rtc_time.tm_min, rtc_time.tm_sec); + } else if (strncmp(cmdline, "setrtctime", 10) == 0) { + /* Point past the string and one whitespace */ + cmdline += 11; + ret = sscanf(cmdline, "%02d/%02d/%04d, %02d:%02d:%02d", &rtc_time.tm_mon, &rtc_time.tm_mday, + &rtc_time.tm_year, &rtc_time.tm_hour, &rtc_time.tm_min, &rtc_time.tm_sec); + + if (ret < 6) { + fprintf(stderr, "\nPlease check your input\n"); + return; + } + + /* months should be in the range 0 to 11 */ + rtc_time.tm_mon -= 1; + /* years should be number of years since 1900 */ + rtc_time.tm_year -= 1900; + ret = ioctl(rtc_fd, RTC_SET_TIME, &rtc_time); + if (ret == -1) + perror("RTC_SET_TIME ioctl"); + } else if (strncmp(cmdline, "getwakealarm", 12) == 0) { + ret = ioctl(rtc_fd, RTC_WKALM_RD, &rtc_wakealarm); + if (ret == -1) + perror("RTC_WKALM_RD ioctl"); + else { + fprintf(stderr, "\nRTC alarm is %s and %s\n", + rtc_wakealarm.enabled ? "enabled" : "disabled", + rtc_wakealarm.pending ? "pending": "not pending"); + fprintf(stderr, "\nCurrent alarm date and time is %02d/%02d/%04d, %02d:%02d:%02d\n", + rtc_wakealarm.time.tm_mon + 1, rtc_wakealarm.time.tm_mday, + rtc_wakealarm.time.tm_year + 1900, rtc_wakealarm.time.tm_hour, + rtc_wakealarm.time.tm_min, rtc_wakealarm.time.tm_sec); + } + } else if (strncmp(cmdline, "setwakealarm", 12) == 0) { + fprintf(stderr, "\nSetting alarm interrupt...Press Ctrl+C to abort\n\n"); + fflush(stderr); + + /* Point past the string and one whitespace */ + cmdline += 13; + ret = sscanf(cmdline, "%02d/%02d/%04d, %02d:%02d:%02d", + &rtc_wakealarm.time.tm_mon, &rtc_wakealarm.time.tm_mday, + &rtc_wakealarm.time.tm_year, &rtc_wakealarm.time.tm_hour, + &rtc_wakealarm.time.tm_min, &rtc_wakealarm.time.tm_sec); + + if (ret < 6) { + fprintf(stderr, "\nPlease check your input\n"); + return; + } + + /* months should be in the range 0 to 11 */ + rtc_wakealarm.time.tm_mon -= 1; + /* years should be number of years since 1900 */ + rtc_wakealarm.time.tm_year -= 1900; + + /* Enable wake alarm interrupt */ + rtc_wakealarm.enabled = 1; + + /* Set pending to 0 */ + rtc_wakealarm.pending = 1; + + /* Set handler for SIGINT */ + signal(SIGINT, alarminthandler); + + ret = ioctl(rtc_fd, RTC_WKALM_SET, &rtc_wakealarm); + if (ret == -1) { + perror("RTC_WKALM_SET ioctl"); + return; + } + + while (1) { + ret = ioctl(rtc_fd, RTC_WKALM_RD, &rtc_wakealarm); + if (ret == -1) { + perror("RTC_WKALM_RD ioctl"); + return; + } + + if (!rtc_wakealarm.enabled) { + /* We could be here either because we received the alarm + * interrupt, or the SIGINT handler was executed. To + * differentiate between the two cases, we use the flag. + */ + if (!signal_recvd) + fprintf(stderr, "\nReceived alarm interrupt\n"); + else + fprintf(stderr, "\nAborting...\n"); + + fflush(stderr); + break; + } + } + + /* In case we did not receive a signal, and we fall through */ + alarminthandler(SIGINT); + signal_recvd = 0; + } else if (strncmp(cmdline, "wakealarmoff", 12) == 0) { + fprintf(stderr, "Turning wake alarm interrupt off\n"); + fflush(stderr); + + ret = ioctl(rtc_fd, RTC_WKALM_RD, &rtc_wakealarm); + if (ret == -1) { + perror("RTC_WKALM_RD ioctl"); + return; + } + + /* Disable wake alarm */ + rtc_wakealarm.enabled = 0; + rtc_wakealarm.pending = 0; + ret = ioctl(rtc_fd, RTC_WKALM_SET, &rtc_wakealarm); + + if (ret == -1) + perror("RTC_WKALM_SET ioctl"); + } else if (strncmp(cmdline, "getperiodicrate", 15) == 0) { + unsigned long rate; + + ret = ioctl(rtc_fd, RTC_IRQP_READ, &rate); + if (ret == -1) { + if (errno == ENOTTY) + fprintf(stderr, "\nNo periodic interrupt support\n"); + else + perror("RTC_IRQP_READ ioctl"); + + return; + } + + fprintf(stderr, "\nPeriodic interrupt rate is %luHz\n", rate); + } else if (strncmp(cmdline, "setperiodicrate", 15) == 0) { + unsigned long rate; + + cmdline += 16; + + sscanf(cmdline, "%lu", &rate); + /* bounds check */ + if (rate < 2 || rate > 8192) { + fprintf(stderr, "\nInvalid rate specified\n"); + return; + } + + /* the rate should be a power of 2 */ + if (rate & (rate - 1)) { + fprintf(stderr, "\nInvalid rate. Only power of 2 allowed\n"); + return; + } + + ret = ioctl(rtc_fd, RTC_IRQP_SET, rate); + if (ret == -1) { + if (errno == ENOTTY) + fprintf(stderr, "\nCannot change periodic interrupt rate\n"); + else + perror("RTC_IRQP_SET ioctl"); + + return; + } + } else if (strncmp(cmdline, "periodicinton", 13) == 0) { + /* Set default handler for SIGINT */ + signal(SIGINT, periodicinthandler); + + ret = ioctl(rtc_fd, RTC_PIE_ON, 0); + if (ret == -1) { + perror("RTC_PIE_ON ioctl"); + return; + } + + fprintf(stderr, "\nChecking periodic interrupt rate...Press Ctrl+C to abort\n\n"); + fflush(stderr); + + loop = 1; + while (loop) { + struct timeval tv = {5, 0}; + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(rtc_fd, &readfds); + + ret = select(rtc_fd + 1, &readfds, NULL, NULL, &tv); + if (ret == -1) { + if (errno != EINTR) + perror("select"); + + /* Break the loop */ + loop = 0; + } else { + /* Non blocking read */ + ret = read(rtc_fd, &data, sizeof(unsigned long)); + if (ret == -1) { + perror("read"); + loop = 0; + } else { + fprintf(stderr, "."); + irqcount++; + } + } + } + + /* Turn off periodic interrupts */ + ret = ioctl(rtc_fd, RTC_PIE_OFF, 0); + if (ret == -1) + perror("RTC_PIE_OFF ioctl"); + } else if (strncmp(cmdline, "periodicintoff", 14) == 0) { + fprintf(stderr, "Turning periodic interrupt off\n"); + fflush(stderr); + + ret = ioctl(rtc_fd, RTC_PIE_OFF, 0); + if (ret == -1) + perror("RTC_PIE_OFF ioctl"); + } else if (strncmp(cmdline, "license", 7) == 0) { + show_license(); + } else if (strncmp(cmdline, "exit", 4) == 0) { + close(rtc_fd); + printf("\nExiting...\n"); + exit(EXIT_SUCCESS); + } else { + printf("\nUnknown command\n"); + print_usage(); + } +} + +int main(int argc, char *argv[]) +{ + char *cmdline= NULL; + + printf("RTC sample application version: %s\n", RTC_APP_VERSION); + printf("Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "This sample application comes with ABSOLUTELY NO WARRANTY;\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions; type `license' for details.\n\n"); + + /* Handler for Ctrl+C */ + signal(SIGINT, sighandler); + + switch(argc) { + case 2: + rtc = argv[1]; + /* FALL THROUGH */ + case 1: + break; + default: + fprintf(stderr, "usage: rtc_test [rtcdev]\n"); + return 1; + } + + rtc_fd = open(rtc, O_RDONLY); + if (rtc_fd == -1) { + perror(rtc); + exit(errno); + } + + while (1) { + cmdline = readline(show_prompt()); + parse_cmd(cmdline); + /* Free the memory malloc'ed by readline */ + free(cmdline); + } + + /* Should never reach here */ + return 0; +} diff --git a/meta-steppeeagle/recipes-applications/rtc-test/rtc-test_1.0.bb b/meta-steppeeagle/recipes-applications/rtc-test/rtc-test_1.0.bb new file mode 100644 index 00000000..868c63c9 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/rtc-test/rtc-test_1.0.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "Sample application for AMD RTC driver" +SECTION = "applications" +LICENSE = "BSD" +DEPENDS = "readline" +LIC_FILES_CHKSUM = "file://rtc-test.c;md5=cdf9bfd59714d20025056dbfaaf31134" + +PR = "r1" +PV = "1.0" + +SRC_URI = "file://rtc-test.c" + +S = "${WORKDIR}" + +TARGET_CC_ARCH += "${LDFLAGS}" + +do_compile() { + ${CC} rtc-test.c -o rtc-test -lreadline +} + +do_install() { + install -d ${D}${bindir} + install -m 0755 rtc-test ${D}${bindir} +} diff --git a/meta-steppeeagle/recipes-applications/smbus-test/files/LICENSE b/meta-steppeeagle/recipes-applications/smbus-test/files/LICENSE new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/meta-steppeeagle/recipes-applications/smbus-test/files/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/meta-steppeeagle/recipes-applications/smbus-test/files/i2c-dev.h b/meta-steppeeagle/recipes-applications/smbus-test/files/i2c-dev.h new file mode 100644 index 00000000..b9358174 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/smbus-test/files/i2c-dev.h @@ -0,0 +1,335 @@ +/* + i2c-dev.h - i2c-bus driver, char device interface + + Copyright (C) 1995-97 Simon G. Vogl + Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301 USA. +*/ + +/* $Id: i2c-dev.h 5894 2010-12-12 13:22:29Z khali $ */ + +#ifndef LIB_I2CDEV_H +#define LIB_I2CDEV_H + +#include <linux/types.h> +#include <sys/ioctl.h> + + +/* -- i2c.h -- */ + + +/* + * I2C Message - used for pure i2c transaction, also from /dev interface + */ +struct i2c_msg { + __u16 addr; /* slave address */ + unsigned short flags; +#define I2C_M_TEN 0x10 /* we have a ten bit chip address */ +#define I2C_M_RD 0x01 +#define I2C_M_NOSTART 0x4000 +#define I2C_M_REV_DIR_ADDR 0x2000 +#define I2C_M_IGNORE_NAK 0x1000 +#define I2C_M_NO_RD_ACK 0x0800 + short len; /* msg length */ + char *buf; /* pointer to msg data */ +}; + +/* To determine what functionality is present */ + +#define I2C_FUNC_I2C 0x00000001 +#define I2C_FUNC_10BIT_ADDR 0x00000002 +#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ +#define I2C_FUNC_SMBUS_PEC 0x00000008 +#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_QUICK 0x00010000 +#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 +#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 +#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 +#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 +#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 +#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 +#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 +#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 +#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 +#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ +#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ + +#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ + I2C_FUNC_SMBUS_WRITE_BYTE) +#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ + I2C_FUNC_SMBUS_WRITE_BYTE_DATA) +#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA) +#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) +#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) + +/* Old name, for compatibility */ +#define I2C_FUNC_SMBUS_HWPEC_CALC I2C_FUNC_SMBUS_PEC + +/* + * Data for SMBus Messages + */ +#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ +#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */ +union i2c_smbus_data { + __u8 byte; + __u16 word; + __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ + /* and one more for PEC */ +}; + +/* smbus_access read or write markers */ +#define I2C_SMBUS_READ 1 +#define I2C_SMBUS_WRITE 0 + +/* SMBus transaction types (size parameter in the above functions) + Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */ +#define I2C_SMBUS_QUICK 0 +#define I2C_SMBUS_BYTE 1 +#define I2C_SMBUS_BYTE_DATA 2 +#define I2C_SMBUS_WORD_DATA 3 +#define I2C_SMBUS_PROC_CALL 4 +#define I2C_SMBUS_BLOCK_DATA 5 +#define I2C_SMBUS_I2C_BLOCK_BROKEN 6 +#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS_I2C_BLOCK_DATA 8 + + +/* ----- commands for the ioctl like i2c_command call: + * note that additional calls are defined in the algorithm and hw + * dependent layers - these can be listed here, or see the + * corresponding header files. + */ + /* -> bit-adapter specific ioctls */ +#define I2C_RETRIES 0x0701 /* number of times a device address */ + /* should be polled when not */ + /* acknowledging */ +#define I2C_TIMEOUT 0x0702 /* set timeout - call with int */ + + +/* this is for i2c-dev.c */ +#define I2C_SLAVE 0x0703 /* Change slave address */ + /* Attn.: Slave address is 7 or 10 bits */ +#define I2C_SLAVE_FORCE 0x0706 /* Change slave address */ + /* Attn.: Slave address is 7 or 10 bits */ + /* This changes the address, even if it */ + /* is already taken! */ +#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */ + +#define I2C_FUNCS 0x0705 /* Get the adapter functionality */ +#define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/ +#define I2C_PEC 0x0708 /* != 0 for SMBus PEC */ + +#define I2C_SMBUS 0x0720 /* SMBus-level access */ + +/* -- i2c.h -- */ + + +/* Note: 10-bit addresses are NOT supported! */ + +/* This is the structure as used in the I2C_SMBUS ioctl call */ +struct i2c_smbus_ioctl_data { + char read_write; + __u8 command; + int size; + union i2c_smbus_data *data; +}; + +/* This is the structure as used in the I2C_RDWR ioctl call */ +struct i2c_rdwr_ioctl_data { + struct i2c_msg *msgs; /* pointers to i2c_msgs */ + int nmsgs; /* number of i2c_msgs */ +}; + + +static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, + int size, union i2c_smbus_data *data) +{ + struct i2c_smbus_ioctl_data args; + + args.read_write = read_write; + args.command = command; + args.size = size; + args.data = data; + return ioctl(file,I2C_SMBUS,&args); +} + + +static inline __s32 i2c_smbus_write_quick(int file, __u8 value) +{ + return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL); +} + +static inline __s32 i2c_smbus_read_byte(int file) +{ + union i2c_smbus_data data; + if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data)) + return -1; + else + return 0x0FF & data.byte; +} + +static inline __s32 i2c_smbus_write_byte(int file, __u8 value) +{ + return i2c_smbus_access(file,I2C_SMBUS_WRITE,value, + I2C_SMBUS_BYTE,NULL); +} + +static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command) +{ + union i2c_smbus_data data; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_BYTE_DATA,&data)) + return -1; + else + return 0x0FF & data.byte; +} + +static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command, + __u8 value) +{ + union i2c_smbus_data data; + data.byte = value; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_BYTE_DATA, &data); +} + +static inline __s32 i2c_smbus_read_word_data(int file, __u8 command) +{ + union i2c_smbus_data data; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_WORD_DATA,&data)) + return -1; + else + return 0x0FFFF & data.word; +} + +static inline __s32 i2c_smbus_write_word_data(int file, __u8 command, + __u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_WORD_DATA, &data); +} + +static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value) +{ + union i2c_smbus_data data; + data.word = value; + if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_PROC_CALL,&data)) + return -1; + else + return 0x0FFFF & data.word; +} + + +/* Returns the number of read bytes */ +static inline __s32 i2c_smbus_read_block_data(int file, __u8 command, + __u8 *values) +{ + union i2c_smbus_data data; + int i; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_BLOCK_DATA,&data)) + return -1; + else { + for (i = 1; i <= data.block[0]; i++) + values[i-1] = data.block[i]; + return data.block[0]; + } +} + +static inline __s32 i2c_smbus_write_block_data(int file, __u8 command, + __u8 length, const __u8 *values) +{ + union i2c_smbus_data data; + int i; + if (length > 32) + length = 32; + for (i = 1; i <= length; i++) + data.block[i] = values[i-1]; + data.block[0] = length; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_BLOCK_DATA, &data); +} + +/* Returns the number of read bytes */ +/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you + ask for less than 32 bytes, your code will only work with kernels + 2.6.23 and later. */ +static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, + __u8 length, __u8 *values) +{ + union i2c_smbus_data data; + int i; + + if (length > 32) + length = 32; + data.block[0] = length; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN : + I2C_SMBUS_I2C_BLOCK_DATA,&data)) + return -1; + else { + for (i = 1; i <= data.block[0]; i++) + values[i-1] = data.block[i]; + return data.block[0]; + } +} + +static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, + __u8 length, + const __u8 *values) +{ + union i2c_smbus_data data; + int i; + if (length > 32) + length = 32; + for (i = 1; i <= length; i++) + data.block[i] = values[i-1]; + data.block[0] = length; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_I2C_BLOCK_BROKEN, &data); +} + +/* Returns the number of read bytes */ +static inline __s32 i2c_smbus_block_process_call(int file, __u8 command, + __u8 length, __u8 *values) +{ + union i2c_smbus_data data; + int i; + if (length > 32) + length = 32; + for (i = 1; i <= length; i++) + data.block[i] = values[i-1]; + data.block[0] = length; + if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_BLOCK_PROC_CALL,&data)) + return -1; + else { + for (i = 1; i <= data.block[0]; i++) + values[i-1] = data.block[i]; + return data.block[0]; + } +} + + +#endif /* LIB_I2CDEV_H */ diff --git a/meta-steppeeagle/recipes-applications/smbus-test/files/smbus-test.c b/meta-steppeeagle/recipes-applications/smbus-test/files/smbus-test.c new file mode 100644 index 00000000..128c5391 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/smbus-test/files/smbus-test.c @@ -0,0 +1,632 @@ +/***************************************************************************** +* +* Copyright (c) 2014, Advanced Micro Devices, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Advanced Micro Devices, Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +***************************************************************************/ +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <signal.h> +#include <dirent.h> + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/stat.h> + +#include <readline/readline.h> + +#include "i2c-dev.h" + +#define SMBUS_APP_VERSION "0.1" + +static int adapter_nr = -1; +static int slave_addr = 0xFF; +static char filename[20]; +static int fd = -1; + +char *show_prompt(void) +{ + return "$ "; +} + +void sighandler(int sig) +{ + printf("\n%s", show_prompt()); +} + +void show_license(void) +{ + printf("/*****************************************************************************\n" + "*\n" + "* Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "* All rights reserved.\n" + "*\n" + "* Redistribution and use in source and binary forms, with or without\n" + "* modification, are permitted provided that the following conditions are met:\n" + "* * Redistributions of source code must retain the above copyright\n" + "* notice, this list of conditions and the following disclaimer.\n" + "* * Redistributions in binary form must reproduce the above copyright\n" + "* notice, this list of conditions and the following disclaimer in the\n" + "* documentation and/or other materials provided with the distribution.\n" + "* * Neither the name of Advanced Micro Devices, Inc. nor the names of\n" + "* its contributors may be used to endorse or promote products derived\n" + "* from this software without specific prior written permission.\n" + "*\n" + "* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n" + "* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n" + "* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n" + "* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY\n" + "* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n" + "* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n" + "* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" + "* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" + "* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n" + "* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "*\n" + "*\n" + "***************************************************************************/\n"); +} + +void print_usage(void) +{ + printf("\nCommands Supported ->\n"); + printf(" enumerate : List all adapters available\n"); + printf(" setadapternum <num> : Set the adapter number\n"); + printf(" getadapternum : Get the current adapter number\n"); + printf(" setslaveaddr <addr> : Set the slave device address\n"); + printf(" getslaveaddr : Get the current slave device address\n"); + printf(" getadapterfunc : Displays the functionalities supported by the adapter\n"); + printf(" quicksend <bit> : Sends a single bit (0 or 1) to the device\n"); + printf(" receivebyte : Receive a single byte from the slave device\n"); + printf(" sendbyte <byte> : Sends a single byte to the slave device\n"); + printf(" readbyte <register> : Reads a byte at register of the slave device\n"); + printf(" writebyte <register> <byte> : Writes a byte at register of the slave device\n"); + printf(" readword <register> : Reads a word at register of the slave device\n"); + printf(" writeword <register> <word> : Writes a word at register of the slave device\n"); + printf(" readblock <register> : Reads a block of data from register of the slave device\n"); + printf(" writeblock <register> <filename> : Writes a block of data read from filename to register\n" + " of the slave device\n"); + printf(" license : Displays the terms of LICENSE for this application\n"); + printf(" help : Displays help text\n"); + printf(" exit : Exits the application\n\n"); +} + +void parse_cmd(const char *cmdline) +{ + struct i2c_smbus_ioctl_data param; + union i2c_smbus_data smbus_data; + unsigned long funcs; + + if (strncmp(cmdline, "enumerate", 9) == 0) { + DIR *dir; + struct dirent *dir_entry; + int adapter_found = 0; + + /* Get the directory handle */ + if ((dir = opendir("/dev")) == NULL) { + printf("Failed to open directory /dev. Probably you " + "do not have right privilege!\n\n"); + exit(EXIT_FAILURE); + } + + /* Iterate over all the directory entries */ + while ((dir_entry = readdir(dir)) != NULL) { + /* + * If the file is a character device, and its signature + * matches i2c-x, then we print the corresponding file. + */ + if ((dir_entry->d_type == DT_CHR) && + (strncmp(dir_entry->d_name, "i2c-", 4) == 0)) { + printf("%s\n", dir_entry->d_name); + adapter_found = 1; + } + } + + printf("\n"); + + /* + * In case we did not find even a single adapter, we print a + * message and exit. + */ + if (!adapter_found) { + printf("No adapters found, load i2c-dev kernel module and try again\n\n"); + exit(EXIT_FAILURE); + } + } else if (strncmp(cmdline, "setadapternum", 13) == 0) { + int input; + int file_desc; + + cmdline += 14; + if (sscanf(cmdline, "%d", &input) < 1) { + printf("Invalid inputs, please try again\n\n"); + return; + } + + snprintf(filename, 19, "/dev/i2c-%d", input); + file_desc = open(filename, O_RDWR); + if (file_desc < 0) { + printf("Error opening file %s\n\n", filename); + return; + } + + /* Once we have validated inputs, we store them into the global + * variables used at other places in the program. + */ + fd = file_desc; + adapter_nr = input; + printf("Adapter Number set to %d\n\n", adapter_nr); + } else if (strncmp(cmdline, "getadapternum", 13) == 0) { + if (adapter_nr == -1) + printf("Adapter Number not set\n\n"); + else + printf("Adapter Number set to %d\n\n", adapter_nr); + } else if (strncmp(cmdline, "setslaveaddr", 12) == 0) { + int addr; + + cmdline += 13; + if (sscanf(cmdline, "0x%x", &addr) < 1) { + printf("Invalid inputs, please try again\n\n"); + return; + } + + /* Set the slave address */ + if (ioctl(fd, I2C_SLAVE, addr) < 0) { + printf("Error setting slave address. Please make sure " + "to provide 7-bit slave address\n\n"); + return; + } + + slave_addr = addr; + printf("Slave Address set to 0x%x\n\n", slave_addr); + } else if (strncmp(cmdline, "getslaveaddr", 12) == 0) { + if (slave_addr == 0xFF) + printf("Slave Address not set\n\n"); + else + printf("Slave Address set to 0x%x\n\n", slave_addr); + } else if (strncmp(cmdline, "getadapterfunc", 14) == 0) { + if (adapter_nr == -1) { + printf("Please set adapter first\n\n"); + return; + } + + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (funcs & I2C_FUNC_I2C) + printf("I2C_FUNC_I2C\n"); + if (funcs & I2C_FUNC_10BIT_ADDR) + printf("I2C_FUNC_10BIT_ADDR\n"); + if (funcs & I2C_FUNC_PROTOCOL_MANGLING) + printf("I2C_FUNC_PROTOCOL_MANGLING\n"); + if (funcs & I2C_FUNC_SMBUS_PEC) + printf("I2C_FUNC_SMBUS_PEC\n"); + if (funcs & I2C_FUNC_SMBUS_BLOCK_PROC_CALL) + printf("I2C_FUNC_SMBUS_BLOCK_PROC_CALL\n"); + if (funcs & I2C_FUNC_SMBUS_QUICK) + printf("I2C_FUNC_SMBUS_QUICK\n"); + if (funcs & I2C_FUNC_SMBUS_READ_BYTE) + printf("I2C_FUNC_SMBUS_READ_BYTE\n"); + if (funcs & I2C_FUNC_SMBUS_WRITE_BYTE) + printf("I2C_FUNC_SMBUS_WRITE_BYTE\n"); + if (funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA) + printf("I2C_FUNC_SMBUS_READ_BYTE_DATA\n"); + if (funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA) + printf("I2C_FUNC_SMBUS_WRITE_BYTE_DATA\n"); + if (funcs & I2C_FUNC_SMBUS_READ_WORD_DATA) + printf("I2C_FUNC_SMBUS_READ_WORD_DATA\n"); + if (funcs & I2C_FUNC_SMBUS_WRITE_WORD_DATA) + printf("I2C_FUNC_SMBUS_WRITE_WORD_DATA\n"); + if (funcs & I2C_FUNC_SMBUS_PROC_CALL) + printf("I2C_FUNC_SMBUS_PROC_CALL\n"); + if (funcs & I2C_FUNC_SMBUS_READ_BLOCK_DATA) + printf("I2C_FUNC_SMBUS_READ_BLOCK_DATA\n"); + if (funcs & I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) + printf("I2C_FUNC_SMBUS_WRITE_BLOCK_DATA\n"); + if (funcs & I2C_FUNC_SMBUS_READ_I2C_BLOCK) + printf("I2C_FUNC_SMBUS_READ_I2C_BLOCK\n"); + if (funcs & I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) + printf("I2C_FUNC_SMBUS_WRITE_I2C_BLOCK\n"); + + printf("\n"); + } else if (strncmp(cmdline, "quicksend", 9) == 0) { + int bit; + + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (!(funcs & I2C_FUNC_SMBUS_QUICK)) { + printf("SMBus Quick command not supported by the adapter\n\n"); + return; + } + + cmdline += 10; + if (sscanf(cmdline, "%d", &bit) < 1) { + printf("Invalid input, please try again\n\n"); + return; + } + + /* Sanity check */ + if ((bit != 0) && (bit != 1)) { + printf("Only 0 or 1 is allowed\n\n"); + return; + } + + memset(¶m, 0, sizeof(struct i2c_smbus_ioctl_data)); + param.data = NULL; + + if (bit) + param.read_write = I2C_SMBUS_READ; + else + param.read_write = I2C_SMBUS_WRITE; + + param.size = I2C_SMBUS_QUICK; + if (ioctl(fd, I2C_SMBUS, ¶m) == -1) { + printf("SMBus Quick command failed\n\n"); + return; + } + + printf("Quick Send %d successfull\n\n", bit); + } else if (strncmp(cmdline, "receivebyte", 11) == 0) { + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (!(funcs & I2C_FUNC_SMBUS_BYTE)) { + printf("SMBus receivebyte command not supported by adapter\n"); + return; + } + + memset(¶m, 0, sizeof(struct i2c_smbus_ioctl_data)); + memset(&smbus_data, 0, sizeof(union i2c_smbus_data)); + param.data = &smbus_data; + + param.read_write = I2C_SMBUS_READ; + param.size = I2C_SMBUS_BYTE; + if (ioctl(fd, I2C_SMBUS, ¶m) == -1) { + printf("SMBus Receive Byte command failed\n\n"); + return; + } + + printf("Byte Received 0x%x\n\n", param.data->byte); + } else if (strncmp(cmdline, "sendbyte", 8) == 0) { + int byte; + + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (!(funcs & I2C_FUNC_SMBUS_BYTE)) { + printf("SMBus sendbyte command not supported by adapter\n"); + return; + } + + cmdline += 9; + if (sscanf(cmdline, "0x%x", &byte) < 1) { + printf("Invalid inputs, please try again\n\n"); + return; + } + + memset(¶m, 0, sizeof(struct i2c_smbus_ioctl_data)); + param.data = NULL; + + param.read_write = I2C_SMBUS_WRITE; + param.command = byte; + param.size = I2C_SMBUS_BYTE; + if (ioctl(fd, I2C_SMBUS, ¶m) == -1) { + printf("SMBus Send Byte command failed\n\n"); + return; + } + + printf("Sent 0x%x to slave\n\n", byte); + } else if (strncmp(cmdline, "readbyte", 8) == 0) { + int reg; + + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (!(funcs & I2C_FUNC_SMBUS_BYTE_DATA)) { + printf("SMBus readbyte command not supported by adapter\n"); + return; + } + + cmdline += 9; + if (sscanf(cmdline, "0x%x", ®) < 1) { + printf("Invalid inputs, please try again\n\n"); + return; + } + + memset(¶m, 0, sizeof(struct i2c_smbus_ioctl_data)); + memset(&smbus_data, 0, sizeof(union i2c_smbus_data)); + param.data = &smbus_data; + + param.command = reg; + param.read_write = I2C_SMBUS_READ; + param.size = I2C_SMBUS_BYTE_DATA; + if (ioctl(fd, I2C_SMBUS, ¶m) == -1) { + printf("SMBus Read Byte Data command failed\n\n"); + return; + } + + printf("Read 0x%x at register 0x%x of the slave\n\n", param.data->byte, reg); + } else if (strncmp(cmdline, "writebyte", 9) == 0) { + int reg, byte; + + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (!(funcs & I2C_FUNC_SMBUS_BYTE_DATA)) { + printf("SMBus writebyte command not supported by adapter\n"); + return; + } + + cmdline += 10; + if (sscanf(cmdline, "0x%x 0x%x", ®, &byte) < 2) { + printf("Invalid inputs, please try again\n\n"); + return; + } + + memset(¶m, 0, sizeof(struct i2c_smbus_ioctl_data)); + memset(&smbus_data, 0, sizeof(union i2c_smbus_data)); + param.data = &smbus_data; + + param.command = reg; + param.read_write = I2C_SMBUS_WRITE; + param.size = I2C_SMBUS_BYTE_DATA; + param.data->byte = byte; + if (ioctl(fd, I2C_SMBUS, ¶m) == -1) { + printf("SMBus Write Byte Data command failed\n\n"); + return; + } + + printf("Written 0x%x to register 0x%x of the slave\n\n", byte, reg); + } else if (strncmp(cmdline, "readword", 8) == 0) { + int reg; + + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (!(funcs & I2C_FUNC_SMBUS_WORD_DATA)) { + printf("SMBus readword command not supported by adapter\n"); + return; + } + + cmdline += 9; + if (sscanf(cmdline, "0x%x", ®) < 1) { + printf("Invalid inputs, please try again\n\n"); + return; + } + + memset(¶m, 0, sizeof(struct i2c_smbus_ioctl_data)); + memset(&smbus_data, 0, sizeof(union i2c_smbus_data)); + param.data = &smbus_data; + + param.command = reg; + param.read_write = I2C_SMBUS_READ; + param.size = I2C_SMBUS_WORD_DATA; + if (ioctl(fd, I2C_SMBUS, ¶m) == -1) { + printf("SMBus Read Word Data command failed\n\n"); + return; + } + + printf("Read 0x%.4x at register 0x%x of the slave\n\n", param.data->word, reg); + } else if (strncmp(cmdline, "writeword", 9) == 0) { + int reg, word; + + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (!(funcs & I2C_FUNC_SMBUS_WORD_DATA)) { + printf("SMBus writeword command not supported by adapter\n"); + return; + } + + cmdline += 10; + if (sscanf(cmdline, "0x%x 0x%x", ®, &word) < 2) { + printf("Invalid inputs, please try again\n\n"); + return; + } + + memset(¶m, 0, sizeof(struct i2c_smbus_ioctl_data)); + memset(&smbus_data, 0, sizeof(union i2c_smbus_data)); + param.data = &smbus_data; + + param.command = reg; + param.read_write = I2C_SMBUS_WRITE; + param.size = I2C_SMBUS_WORD_DATA; + param.data->word = word; + if (ioctl(fd, I2C_SMBUS, ¶m) == -1) { + printf("SMBus Write Word Data command failed\n\n"); + return; + } + + printf("Written 0x%x to register 0x%x of the slave\n\n", word, reg); + } else if (strncmp(cmdline, "readblock", 9) == 0) { + int reg; + int i; + + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (!(funcs & I2C_FUNC_SMBUS_BLOCK_DATA)) { + printf("SMBus readblock command not supported by adapter\n"); + return; + } + + cmdline += 10; + if (sscanf(cmdline, "0x%x", ®) < 1) { + printf("Invalid inputs, please try again\n\n"); + return; + } + + memset(¶m, 0, sizeof(struct i2c_smbus_ioctl_data)); + memset(&smbus_data, 0, sizeof(union i2c_smbus_data)); + param.data = &smbus_data; + + param.command = reg; + param.read_write = I2C_SMBUS_READ; + param.size = I2C_SMBUS_BLOCK_DATA; + if (ioctl(fd, I2C_SMBUS, ¶m) == -1) { + printf("SMBus Read Block Data command failed\n\n"); + return; + } + + printf("Reading %d bytes from register 0x%x:\n", param.data->block[0], reg); + for (i = 1; i <= param.data->block[0]; i++) + printf("0x%.2x ", param.data->block[i]); + printf("\n\n"); + } else if (strncmp(cmdline, "writeblock", 10) == 0) { + int reg; + char infile[256]; + FILE *file; + int data; + int num_bytes = 0; + int i; + + /* Get the adapter functionality */ + if (ioctl(fd, I2C_FUNCS, &funcs) < 0) { + printf("Error getting adapter functionalities\n\n"); + return; + } + + if (!(funcs & I2C_FUNC_SMBUS_BLOCK_DATA)) { + printf("SMBus writeblock command not supported by adapter\n"); + return; + } + + cmdline += 11; + if (sscanf(cmdline, "0x%x %s", ®, infile) < 2) { + printf("Invalid inputs, please try again\n\n"); + return; + } + + /* open infile for reading */ + if ((file = fopen(infile, "r")) == NULL) { + printf("Failed to open file %s\n\n", infile); + return; + } + + /* setup parameters to the IOCTL call */ + memset(¶m, 0, sizeof(struct i2c_smbus_ioctl_data)); + memset(&smbus_data, 0, sizeof(union i2c_smbus_data)); + param.data = &smbus_data; + + param.command = reg; + param.read_write = I2C_SMBUS_WRITE; + param.size = I2C_SMBUS_BLOCK_DATA; + + /* + * populate block data to be sent to the device. SMBus sets a + * limit of 32 bytes to be sent or received in a block. + */ + for (i = 1; i <= 32; i++) { + if (fscanf(file, "0x%x ", &data) == EOF) + break; + + param.data->block[i] = data; + num_bytes++; + } + + /* The very first block data should be the number of bytes + * in the block. + */ + param.data->block[0] = num_bytes; + + printf("Writing %d bytes to register 0x%.2x of device\n\n", + param.data->block[0], reg); + + /* Execute block write command */ + if (ioctl(fd, I2C_SMBUS, ¶m) == -1) { + printf("SMBus Write Block Data command failed\n\n"); + return; + } + + fclose(file); + } else if (strncmp(cmdline, "license", 7) == 0) { + show_license(); + } else if (strncmp(cmdline, "exit", 4) == 0) { + printf("\nExiting...\n"); + if((fd != -1) && (close(fd) < 0)) + printf("Error closing device\n\n"); + + exit(EXIT_SUCCESS); + } else if (strncmp(cmdline, "help", 4) == 0) { + print_usage(); + } else { + printf("\nUnknown command\n"); + print_usage(); + } +} + +int main(void) +{ + char *cmdline= NULL; + + printf("SMBus sample application version: %s\n", SMBUS_APP_VERSION); + printf("Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "This sample application comes with ABSOLUTELY NO WARRANTY;\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions; type `license` for details.\n\n"); + + /* Handler for Ctrl+C */ + signal(SIGINT, sighandler); + + while (1) { + cmdline = readline(show_prompt()); + parse_cmd(cmdline); + /* Free the memory malloc'ed by readline */ + free(cmdline); + } + + /* Should never reach here */ + return 0; +} diff --git a/meta-steppeeagle/recipes-applications/smbus-test/smbus-test_1.0.bb b/meta-steppeeagle/recipes-applications/smbus-test/smbus-test_1.0.bb new file mode 100644 index 00000000..2347b74d --- /dev/null +++ b/meta-steppeeagle/recipes-applications/smbus-test/smbus-test_1.0.bb @@ -0,0 +1,27 @@ +DESCRIPTION = "Sample application for AMD SMBUS driver" +SECTION = "applications" +LICENSE = "BSD | GPLv2" +DEPENDS = "readline" +LIC_FILES_CHKSUM = "file://smbus-test.c;md5=51840771157718d4d562329e476d6917 \ + file://i2c-dev.h;md5=11afa8583cd78137a63feb1a8b24cc51 \ + " + +PR = "r1" +PV = "1.0" + +SRC_URI = "file://smbus-test.c \ + file://i2c-dev.h \ + " + +S = "${WORKDIR}" + +TARGET_CC_ARCH += "${LDFLAGS}" + +do_compile() { + ${CC} smbus-test.c -o smbus-test -lreadline +} + +do_install() { + install -d ${D}${bindir} + install -m 0755 smbus-test ${D}${bindir} +} diff --git a/meta-steppeeagle/recipes-applications/spi-test/files/spirom-test.c b/meta-steppeeagle/recipes-applications/spi-test/files/spirom-test.c new file mode 100644 index 00000000..1c48f7c4 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/spi-test/files/spirom-test.c @@ -0,0 +1,641 @@ +/***************************************************************************** +* +* Copyright (c) 2014, Advanced Micro Devices, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Advanced Micro Devices, Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +***************************************************************************/ +#include <stdint.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <fcntl.h> +#include <string.h> +#include <sys/ioctl.h> +#include <linux/types.h> + +#include "spirom.h" + +#define SPI_APP_VERSION "0.1" + +#define WREN 0x06 +#define WRDI 0x04 +#define RDSR 0x05 +#define RDID 0x9F +#define CHIP_ERASE 0x60 +#define SECTOR_ERASE 0x20 +#define BLOCK_ERASE 0xD8 +#define READ 0x03 +#define WRITE 0x02 + +static void pabort(const char *s) +{ + perror(s); + abort(); +} + +static const char *device = "/dev/spirom0.0"; +static char command[20]; +static int inputfile_fd; +static int outfile_fd;; +static unsigned long address; +static unsigned int num_bytes; + +void show_license(void) +{ + printf("/*****************************************************************************\n" + "*\n" + "* Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "* All rights reserved.\n" + "*\n" + "* Redistribution and use in source and binary forms, with or without\n" + "* modification, are permitted provided that the following conditions are met:\n" + "* * Redistributions of source code must retain the above copyright\n" + "* notice, this list of conditions and the following disclaimer.\n" + "* * Redistributions in binary form must reproduce the above copyright\n" + "* notice, this list of conditions and the following disclaimer in the\n" + "* documentation and/or other materials provided with the distribution.\n" + "* * Neither the name of Advanced Micro Devices, Inc. nor the names of\n" + "* its contributors may be used to endorse or promote products derived\n" + "* from this software without specific prior written permission.\n" + "*\n" + "* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n" + "* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n" + "* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n" + "* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY\n" + "* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n" + "* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n" + "* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" + "* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" + "* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n" + "* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "*\n" + "*\n" + "***************************************************************************/\n"); +} + +void parse_command(int fd) +{ + uint8_t cmd_byte; + struct spi_ioc_transfer tr; + unsigned int bytes_chunks; + unsigned int remaining_bytes; + int ret; + + /* Zero initialize spi_ioc_transfer */ + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + if ((strncmp(command, "WREN", 4) == 0) || + (strncmp(command, "wren", 4) == 0)) { + /* Command without data */ + tr.buf[0] = WREN; + tr.direction = 0; + tr.len = 0; + tr.addr_present = 0; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + } else if ((strncmp(command, "WRDI", 4) == 0) || + (strncmp(command, "wrdi", 4) == 0)) { + /* Command without data */ + tr.buf[0] = WRDI; + tr.direction = 0; + tr.len = 0; + tr.addr_present = 0; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + } else if ((strncmp(command, "CHIPERASE", 4) == 0) || + (strncmp(command, "chiperase", 4) == 0)) { + + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + else if ((tr.buf[1] & 0x02) == 0x00) { + printf("cannot execute command, write is disabled\n"); + exit(1); + } + + /* Command without data */ + tr.buf[0] = CHIP_ERASE; + tr.direction = 0; + tr.len = 0; + tr.addr_present = 0; + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + /* Make sure WIP has been reset */ + while (1) { + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + if ((tr.buf[1] & 0x01) == 0x00) + break; + } + } else if ((strncmp(command, "RDSR", 4) == 0) || + (strncmp(command, "rdsr", 4) == 0)) { + /* Command with response */ + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + /* + * The 1-byte response will be stored in tr.buf, + * so print it out + */ + printf("command: 0x%.2x response: 0x%.2x\n", tr.buf[0], + tr.buf[1]); + } else if ((strncmp(command, "RDID", 4) == 0) || + (strncmp(command, "rdid", 4) == 0)) { + /* Command with response */ + tr.buf[0] = RDID; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 3; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + /* + * The 3-bytes response will be stored in tr.buf, + * so print it out + */ + printf("command: 0x%.2x response: 0x%.2x%.2x%.2x\n", tr.buf[0], + tr.buf[1], tr.buf[2], tr.buf[3]); + } else if ((strncmp(command, "SECTORERASE", 6) ==0) || + (strncmp(command, "sectorerase", 6) ==0)) { + int i; + + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + else if ((tr.buf[1] & 0x02) == 0x00) { + printf("cannot execute command, write is disabled\n"); + exit(1); + } + + /* + * num_bytes here is a little bit of misnomer, it indicates the + * number of sectors to be erased, rather than the number of + * bytes to be erased. + */ + for (i = 0; i < num_bytes; i++) { + /* Write Enable before Sector Erase */ + tr.buf[0] = WREN; + tr.direction = 0; + tr.len = 0; + tr.addr_present = 0; + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + /* Command with address but no data */ + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = SECTOR_ERASE; + tr.buf[3] = address & 0xff; + tr.buf[2] = (address >> 8) & 0xff; + tr.buf[1] = (address >> 16) & 0xff; + tr.addr_present = 1; + tr.direction = 0; + tr.len = 0; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + /* point to the next 4k block */ + address += 4 * 1024; + + /* + * Before the next loop, we need to make sure that WIP + * bit in the output of RDSR has been reset. + */ + while (1) { + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + if ((tr.buf[1] & 0x01) == 0x00) + break; + } + } + } else if ((strncmp(command, "BLOCKERASE", 5) == 0) || + (strncmp(command, "blockerase", 5) == 0)) { + int i; + + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + else if ((tr.buf[1] & 0x02) == 0x00) { + printf("cannot execute command, write is disabled\n"); + exit(1); + } + + /* + * num_bytes indicates the number of blocks to be erased, + * rather than the number of bytes to be erased. + */ + for (i = 0; i < num_bytes; i++) { + /* Write Enable before Block Erase */ + tr.buf[0] = WREN; + tr.direction = 0; + tr.len = 0; + tr.addr_present = 0; + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + /* Command with address but no data */ + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = BLOCK_ERASE; + tr.buf[3] = address & 0xff; + tr.buf[2] = (address >> 8) & 0xff; + tr.buf[1] = (address >> 16) & 0xff; + tr.addr_present = 1; + tr.direction = 0; + tr.len = 0; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + /* point to the next 64k block */ + address += 64 * 1024; + + /* + * Before the next loop, we need to make sure that WIP + * bit in the output of RDSR has been reset. + */ + while (1) { + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + if ((tr.buf[1] & 0x01) == 0x00) + break; + } + } + } else if ((strncmp(command, "READ", 4) == 0) || + (strncmp(command, "read", 4) ==0)) { + int i; + + /* + * We will break down the bytes to be received in chunks of + * of 64-bytes. Data might not be a even multiple of 64. So + * in that case, we will have some remaining bytes <64. We + * handle that separately. + */ + bytes_chunks = num_bytes / 64; + remaining_bytes = num_bytes % 64; + + for (i = 0; i < bytes_chunks; i++) { + /* Command with address and data */ + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = READ; + tr.direction = RECEIVE; + /* + * We will store the address into the buffer in little + * endian order. + */ + tr.buf[3] = address & 0xff; + tr.buf[2] = (address >> 8) & 0xff; + tr.buf[1] = (address >> 16) & 0xff; + tr.len = 64; + tr.addr_present = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + /* Write the data read to output file */ + if (write(outfile_fd, &tr.buf[4], tr.len) < 0) { + perror("write error"); + exit(1); + } + address += 64; + } + + if (remaining_bytes) { + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = READ; + tr.direction = RECEIVE; + tr.buf[3] = address & 0xff; + tr.buf[2] = (address >> 8) & 0xff; + tr.buf[1] = (address >> 16) & 0xff; + tr.len = remaining_bytes; + tr.addr_present = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + if (write(outfile_fd, &tr.buf[4], tr.len) < 0) { + perror("write error"); + exit(1); + } + } + } else if ((strncmp(command, "WRITE", 5) == 0) || + (strncmp(command, "write", 5) ==0)) { + int i; + + /* + * We will break down the bytes to be transmitted in chunks of + * of 64-bytes. Like for read, we might not have data in an + * even multiple of 64 bytes. So we will handle the remaining + * bytes in the end. + */ + + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + else if ((tr.buf[1] & 0x02) == 0x00) { + printf("cannot execute command, write is disabled\n"); + exit(1); + } + + bytes_chunks = num_bytes / 64; + remaining_bytes = num_bytes % 64; + + for (i = 0; i < bytes_chunks; i++) { + tr.buf[0] = WREN; + tr.direction = 0; + tr.len = 0; + tr.addr_present = 0; + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + /* Command with data and address */ + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = WRITE; + tr.direction = TRANSMIT; + /* + * We will store the address into the buffer in little + * endian order. + */ + tr.buf[3] = address & 0xff; + tr.buf[2] = (address >> 8) & 0xff; + tr.buf[1] = (address >> 16) & 0xff; + tr.len = 64; + tr.addr_present = 1; + + /* Read 64 bytes from inputfile to buffer */ + if (read(inputfile_fd, &tr.buf[4], tr.len) < 0) { + perror("read error"); + exit(1); + } + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + address += 64; + + /* + * Before the next loop, we need to make sure that WIP + * bit in the output of RDSR has been reset. + */ + while (1) { + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + if ((tr.buf[1] & 0x01) == 0x00) + break; + } + } + + if (remaining_bytes) { + tr.buf[0] = WREN; + tr.direction = 0; + tr.len = 0; + tr.addr_present = 0; + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = WRITE; + tr.direction = TRANSMIT; + tr.buf[3] = address & 0xff; + tr.buf[2] = (address >> 8) & 0xff; + tr.buf[1] = (address >> 16) & 0xff; + tr.len = remaining_bytes; + tr.addr_present = 1; + + if (read(inputfile_fd, &tr.buf[4], tr.len) < 0) { + perror("read error"); + exit(1); + } + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + while (1) { + memset(&tr, 0, sizeof(struct spi_ioc_transfer)); + tr.buf[0] = RDSR; + tr.direction = RECEIVE; + tr.addr_present = 0; + tr.len = 1; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + if ((tr.buf[1] & 0x01) == 0x00) + break; + } + } + } else + pabort("Unrecognized command, please try again.\n"); +} + +static void print_usage(const char *prog) +{ + printf("\nUsage: sudo %s [-DCAnio] [arguments]\n\n", prog); + puts(" -D --device SPI ROM device to use\n" + " (default /dev/spirom0.0)\n\n" + " -C --command command to send to the device\n" + " (WREN/WRDI/RDSR/RDID/CHIPERASE/SECTORERASE/\n" + " BLOCKERASE/READ/WRITE)\n\n" + " -A --address offset in decimal, into the device to read\n" + " from or write to. For a ROM size of 8MB,\n" + " address can go from 0 to 8388608. Negative\n" + " offsets are not valid, but the program\n" + " won't complain and convert it to its\n" + " unsigned equivalent.\n\n" + " -n --num-bytes number of bytes to be read from or written\n" + " to. Depending on the address, this can\n" + " take values from 0 to 8388608 for a ROM\n" + " size of 8MB.\n\n" + " In case of SECTORERASE and BLOCKERASE\n" + " commands, num-bytes actually takes the\n" + " number of sectors and blocks to be erased\n" + " respectively, rather than the number of\n" + " bytes.\n\n" + " -i --input-file file to be used as input.\n\n" + " -o --output-file file to be used for output. Remember that if\n" + " an existing filename is given, its contents\n" + " will be overwritten.\n" + " -l --license displays the terms of LICENSE for this application\n\n"); + exit(1); +} + +static void parse_opts(int argc, char *argv[]) +{ + if (argc == 1) + print_usage(argv[0]); + + while (1) { + static const struct option lopts[] = { + { "device", 1, 0, 'D' }, + { "command", 1, 0, 'C' }, + { "address", 1, 0, 'A' }, + { "num-bytes", 1, 0, 'n' }, + { "input-file", 1, 0, 'i' }, + { "output-file", 1, 0, 'o' }, + { "license", 0, 0, 'l' }, + { NULL, 0, 0, 0 }, + }; + int c; + + c = getopt_long(argc, argv, "D:C:A:n:i:o:l", lopts, NULL); + + if (c == -1) + break; + + switch (c) { + case 'D': + device = optarg; + break; + case 'C': + memset(command, sizeof(command), 0); + strncpy(command, optarg, sizeof(command)); + break; + case 'A': + address = atol(optarg); + break; + case 'n': + num_bytes = atoi(optarg); + break; + case 'i': + inputfile_fd = open(optarg, O_RDONLY); + if (inputfile_fd < 0) { + printf("Error opening %s\n", optarg); + exit(1); + } + break; + case 'o': + outfile_fd = open(optarg, O_WRONLY | O_CREAT | + O_TRUNC, 0644); + if(outfile_fd < 0) { + printf("Error opening %s\n", optarg); + exit(1); + } + break; + case 'l': + show_license(); + exit(0);; + default: + print_usage(argv[0]); + break; + } + } +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + int fd; + + printf("SPI sample application version: %s\n", SPI_APP_VERSION); + printf("Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "This sample application comes with ABSOLUTELY NO WARRANTY;\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions; type `license' for details.\n\n"); + + parse_opts(argc, argv); + + fd = open(device, O_RDWR); + if (fd < 0) + pabort("can't open device"); + + parse_command(fd); + + return ret; +} diff --git a/meta-steppeeagle/recipes-applications/spi-test/files/spirom.h b/meta-steppeeagle/recipes-applications/spi-test/files/spirom.h new file mode 100644 index 00000000..750719a6 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/spi-test/files/spirom.h @@ -0,0 +1,43 @@ +#ifndef SPIROM_H +#define SPIROM_H + +#include <linux/types.h> + +/*---------------------------------------------------------------------------*/ + +/* IOCTL commands */ + +#define SPI_IOC_MAGIC 'k' + +#define TRANSMIT 1 +#define RECEIVE 2 + +/* + * struct spi_ioc_transfer - interface structure between application and ioctl + * + * @buf: Buffer to hold 1-byte command, 3-bytes address, and 64-byte data for + * transmit or receive. The internal FIFO of our controller can hold a + * maximum of 70 bytes, including the address. But here we assume the + * maximum data excluding address to be 64-bytes long. + * + * @direction: Direction of data transfer, either TRANSMIT or RECEIVE. + * + * @len: Length of data excluding command and address. + * + * @addr_present: Flag to indicate whether 'buf' above contains an address. + */ +struct spi_ioc_transfer { + __u8 buf[64 + 1 + 3]; + __u8 direction; + __u8 len; + __u8 addr_present; +}; + +/* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */ +#define SPI_MSGSIZE(N) \ + ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ + ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0) +#define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) + + +#endif /* SPIROM_H */ diff --git a/meta-steppeeagle/recipes-applications/spi-test/spi-test_1.0.bb b/meta-steppeeagle/recipes-applications/spi-test/spi-test_1.0.bb new file mode 100644 index 00000000..83593cb4 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/spi-test/spi-test_1.0.bb @@ -0,0 +1,27 @@ +DESCRIPTION = "Sample application for AMD SPI driver" +SECTION = "applications" +LICENSE = "BSD" +DEPENDS = "readline" +LIC_FILES_CHKSUM = "file://spirom-test.c;md5=c6d80587d583668ffbfb5828abd58878 \ + file://spirom.h;md5=56f117ed31b82b02182c7a491364d112 \ + " + +PR = "r1" +PV = "1.0" + +SRC_URI = "file://spirom-test.c \ + file://spirom.h \ + " + +S = "${WORKDIR}" + +TARGET_CC_ARCH += "${LDFLAGS}" + +do_compile() { + ${CC} spirom-test.c -o spirom-test -lreadline +} + +do_install() { + install -d ${D}${bindir} + install -m 0755 spirom-test ${D}${bindir} +} diff --git a/meta-steppeeagle/recipes-applications/watchdog-test/files/watchdog-test.c b/meta-steppeeagle/recipes-applications/watchdog-test/files/watchdog-test.c new file mode 100644 index 00000000..77124784 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/watchdog-test/files/watchdog-test.c @@ -0,0 +1,288 @@ +/***************************************************************************** +* +* Copyright (c) 2014, Advanced Micro Devices, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Advanced Micro Devices, Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +***************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <readline/readline.h> +#include <linux/watchdog.h> + +#define WATCHDOG_APP_VERSION "0.1" + +int fd; /* /dev/watchdog file descriptor */ +volatile int ping; + +char *show_prompt(void) +{ + return "$ "; +} + +void sighandler(int sig) +{ + printf("\n%s", show_prompt()); +} + +void pinghandler(int sig) +{ + ping = 0; + printf("\n"); + /* Set the signal handler back to the original */ + signal(SIGINT, sighandler); +} + +void show_license(void) +{ + printf("/*****************************************************************************\n" + "*\n" + "* Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "* All rights reserved.\n" + "*\n" + "* Redistribution and use in source and binary forms, with or without\n" + "* modification, are permitted provided that the following conditions are met:\n" + "* * Redistributions of source code must retain the above copyright\n" + "* notice, this list of conditions and the following disclaimer.\n" + "* * Redistributions in binary form must reproduce the above copyright\n" + "* notice, this list of conditions and the following disclaimer in the\n" + "* documentation and/or other materials provided with the distribution.\n" + "* * Neither the name of Advanced Micro Devices, Inc. nor the names of\n" + "* its contributors may be used to endorse or promote products derived\n" + "* from this software without specific prior written permission.\n" + "*\n" + "* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n" + "* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n" + "* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n" + "* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY\n" + "* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n" + "* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n" + "* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" + "* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" + "* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n" + "* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "*\n" + "*\n" + "***************************************************************************/\n"); +} + +void print_usage() +{ + printf("\nCommands Supported ->\n"); + printf(" disablewatchdog : Disables the Watchdog Timer\n"); + printf(" enablewatchdog : Enables the Watchdog Timer\n"); + printf(" getfeatures : Shows the features supported by the Watchdog implementation\n"); + printf(" getstatus : Gives the current status of Watchdog Timer\n"); + printf(" getbootstatus : Displays the status of Watchdog Hardware after reboot or fresh boot\n"); + printf(" ping : Resets Watchdog Timer at regular intervals\n"); + printf(" gettimeout : Gives the value of Watchdog timeout (in frequency units)\n"); + printf(" gettimeleft : Gives the current value of Watchdog Timer (in frequency units)\n"); + printf(" sendmagicchar : Sends the magic character 'V' to the Watchdog device\n"); + printf(" settimeout <timeout> : Sets the new value for Watchdog timeout (in frequency units)\n"); + printf(" license : Displays the terms of LICENSE for this application\n"); + printf(" help : Displays help text\n"); + printf(" exit : Exits the application\n\n"); +} + +void parse_cmd(const char *cmdline) +{ + if (strncmp(cmdline, "help", 4) == 0) + print_usage(); + else if (strncmp(cmdline, "disablewatchdog", 7) == 0) { + int flags; + + printf("\nDisabling watchdog timer...\n"); + flags = WDIOS_DISABLECARD; + if (ioctl(fd, WDIOC_SETOPTIONS, &flags) < 0) + perror("Could not disable watchdog"); + } else if (strncmp(cmdline, "enablewatchdog", 6) == 0) { + int flags; + + printf("\nEnabling watchdog timer...\n"); + flags = WDIOS_ENABLECARD; + if (ioctl(fd, WDIOC_SETOPTIONS, &flags) < 0) + printf("Could not enable watchdog"); + } else if (strncmp(cmdline, "getfeatures", 10) == 0) { + struct watchdog_info info; + + if(ioctl(fd, WDIOC_GETSUPPORT, &info) < 0) + perror("Could not get watchdog features"); + + printf("\nIdentity:\t\t%s\n", info.identity); + printf("Firmware Version:\t%u\n", info.firmware_version); + printf("Options Set: \n" + "%s%s%s%s%s%s%s%s%s%s%s\n", + info.options & WDIOF_OVERHEAT ? "\t\t\tReset due to CPU overheat\n": "", + info.options & WDIOF_FANFAULT ? "\t\t\tFan failed\n": "", + info.options & WDIOF_EXTERN1 ? "\t\t\tExternal relay 1\n": "", + info.options & WDIOF_EXTERN2 ? "\t\t\tExternal relay 2\n": "", + info.options & WDIOF_POWERUNDER ? "\t\t\tPower bad/power fault\n": "", + info.options & WDIOF_CARDRESET ? "\t\t\tCard previously reset the CPU\n": "", + info.options & WDIOF_POWEROVER ? "\t\t\tPower over voltage\n": "", + info.options & WDIOF_SETTIMEOUT ? "\t\t\tSet timeout (in frequency units)\n": "", + info.options & WDIOF_MAGICCLOSE ? "\t\t\tSupports magic close character\n": "", + info.options & WDIOF_PRETIMEOUT ? "\t\t\tPretimeout (in frequency units)\n": "", + info.options & WDIOF_KEEPALIVEPING ? "\t\t\tKeep alive ping reply\n": ""); + } else if (strncmp(cmdline, "getstatus", 9) == 0) { + int status; + + printf("\n"); + if(ioctl(fd, WDIOC_GETSTATUS, &status) < 0) + perror("Could not get watchdog status"); + + if (status & (1 << 0)) + printf("\nWatchdog device is active\n"); + if (status & (1 << 1)) + printf("Watchdog device opened via /dev/watchdog\n"); + if (status & (1 << 2)) + printf("Received magic char\n"); + if (status & (1 << 3)) + printf("nowayout set\n"); + if (status & (1 << 4)) + printf("Watchdog device unregistered\n"); + } else if (strncmp(cmdline, "getbootstatus", 7) == 0) { + int bootstatus; + + if(ioctl(fd, WDIOC_GETBOOTSTATUS, &bootstatus) < 0) + perror("Could not get bootstatus"); + + printf("\nbootstatus: \n" + "%s%s%s%s%s%s%s%s%s%s%s\n", + bootstatus & WDIOF_OVERHEAT ? "\t\t\tReset due to CPU overheat\n": "", + bootstatus & WDIOF_FANFAULT ? "\t\t\tFan failed\n": "", + bootstatus & WDIOF_EXTERN1 ? "\t\t\tExternal relay 1\n": "", + bootstatus & WDIOF_EXTERN2 ? "\t\t\tExternal relay 2\n": "", + bootstatus & WDIOF_POWERUNDER ? "\t\t\tPower bad/power fault\n": "", + bootstatus & WDIOF_CARDRESET ? "\t\t\tCard previously reset the CPU\n": "", + bootstatus & WDIOF_POWEROVER ? "\t\t\tPower over voltage\n": "", + bootstatus & WDIOF_SETTIMEOUT ? "\t\t\tSet timeout (in frequency units)\n": "", + bootstatus & WDIOF_MAGICCLOSE ? "\t\t\tSupports magic close character\n": "", + bootstatus & WDIOF_PRETIMEOUT ? "\t\t\tPretimeout (in frequency units)\n": "", + bootstatus & WDIOF_KEEPALIVEPING ? "\t\t\tKeep alive ping reply\n": ""); + } else if (strncmp(cmdline, "ping", 4) == 0) { + int dummy; + + printf("\nContinuosly resetting Watchdog...press Ctrl+C to stop\n"); + printf("\nOnce you stop pinging, Watchog Timer will start counting down...\n"); + printf("...If the Watchdog Timer was enabled\n"); + + /* Lets set a different handler for Ctrl+C */ + signal(SIGINT, pinghandler); + + ping = 1; + while (ping) { + if(ioctl(fd, WDIOC_KEEPALIVE, &dummy) < 0) { + perror("Error sending ping"); + break; + } + sleep(1); + } + } else if (strncmp(cmdline, "gettimeout", 10) == 0) { + int timeout; + + if(ioctl(fd, WDIOC_GETTIMEOUT, &timeout) < 0) + perror("Error getting watchdog timeout"); + + printf("\nCurrent setting of timeout is %d frequency units\n", timeout); + } else if (strncmp(cmdline, "gettimeleft", 11) == 0) { + int timeleft; + + if(ioctl(fd, WDIOC_GETTIMELEFT, &timeleft) < 0) + perror("Error getting watchdog timeleft"); + + printf("\nTime left for system reboot/shutdown is %d frequency units\n", timeleft); + } else if (strncmp(cmdline, "sendmagicchar", 9) == 0) { + printf("\nSending magic character to Watchdog device...\n"); + printf("\nWatchdog Timer will be stopped once you exit the application\n"); + if(write(fd, "V", 1) < 0) + perror("Could not send magic character"); + } else if (strncmp(cmdline, "settimeout", 10) == 0) { + const char *charp = cmdline; + int timeout; + + /* Lets point to the end of first token */ + charp += strlen("settimeout"); + /* Skip blank characters */ + while (*charp == ' ' || *charp == '\t' || *charp == '\n') + charp++; + + /* Now we should be pointing to the first 'digit' character */ + timeout = atoi(charp); + + if(ioctl(fd, WDIOC_SETTIMEOUT, &timeout) < 0) { + perror("Could not set watchdog timeout"); + return; + } + + printf("\nSetting timeout to %d frequency units\n", timeout); + printf("Watchdog Timer will start counting down with the new timeout value\n"); + } else if (strncmp(cmdline, "license", 7) == 0) { + show_license(); + } else if (strncmp(cmdline, "exit", 4) == 0) { + printf("\nExiting...\n"); + printf("\nIf the Watchdog Timer was not disabled, and you did not send the magic character,\n" + "Watchdog Timer is still ticking, and your system will reboot soon\n"); + + if(close(fd) < 0) + perror("Error closing /dev/watchdog"); + exit(EXIT_SUCCESS); + } else { + printf("\nUnknown command\n"); + print_usage(); + } +} + +int main(void) +{ + char *cmdline= NULL; + + printf("Watchdog sample application version: %s\n", WATCHDOG_APP_VERSION); + printf("Copyright (c) 2014, Advanced Micro Devices, Inc.\n" + "This sample application comes with ABSOLUTELY NO WARRANTY;\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions; type `license' for details.\n\n"); + + + if ((fd = open("/dev/watchdog", O_WRONLY)) < 0) { + perror("Could not open /dev/watchdog"); + exit(1); + } + + /* Handler for Ctrl+C */ + signal(SIGINT, sighandler); + + while (1) { + cmdline = readline(show_prompt()); + parse_cmd(cmdline); + /* Free the memory malloc'ed by readline */ + free(cmdline); + } + + /* Should never reach here */ + return 0; +} diff --git a/meta-steppeeagle/recipes-applications/watchdog-test/watchdog-test_1.0.bb b/meta-steppeeagle/recipes-applications/watchdog-test/watchdog-test_1.0.bb new file mode 100644 index 00000000..43d511d0 --- /dev/null +++ b/meta-steppeeagle/recipes-applications/watchdog-test/watchdog-test_1.0.bb @@ -0,0 +1,23 @@ +DESCRIPTION = "Sample application for AMD Watchdog driver" +SECTION = "applications" +LICENSE = "BSD" +DEPENDS = "readline" +LIC_FILES_CHKSUM = "file://watchdog-test.c;md5=47ff70acbf47e0bf894330dee1143414" + +PR = "r1" +PV = "1.0" + +SRC_URI = "file://watchdog-test.c" + +S = "${WORKDIR}" + +TARGET_CC_ARCH += "${LDFLAGS}" + +do_compile() { + ${CC} watchdog-test.c -o watchdog-test -lreadline +} + +do_install() { + install -d ${D}${bindir} + install -m 0755 watchdog-test ${D}${bindir} +} diff --git a/meta-steppeeagle/recipes-bsp/formfactor/formfactor/steppeeagle/machconfig b/meta-steppeeagle/recipes-bsp/formfactor/formfactor/steppeeagle/machconfig new file mode 100644 index 00000000..28ca080e --- /dev/null +++ b/meta-steppeeagle/recipes-bsp/formfactor/formfactor/steppeeagle/machconfig @@ -0,0 +1,3 @@ +# Assume a USB mouse and keyboard are connected +HAVE_TOUCHSCREEN=n +HAVE_KEYBOARD=y diff --git a/meta-steppeeagle/recipes-bsp/formfactor/formfactor_0.0.bbappend b/meta-steppeeagle/recipes-bsp/formfactor/formfactor_0.0.bbappend new file mode 100644 index 00000000..6d4804d1 --- /dev/null +++ b/meta-steppeeagle/recipes-bsp/formfactor/formfactor_0.0.bbappend @@ -0,0 +1,2 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + diff --git a/meta-steppeeagle/recipes-core/llvm/llvm3.4.inc b/meta-steppeeagle/recipes-core/llvm/llvm3.4.inc new file mode 100644 index 00000000..a416dfd8 --- /dev/null +++ b/meta-steppeeagle/recipes-core/llvm/llvm3.4.inc @@ -0,0 +1,49 @@ +# +# Since we need LLVM 3.4 but meta-oe currently only supports +# 3.3, override the minimum bits needed to get it to work. +# Eventually this will need to be reconciled with upstream +# + +# Ideally this would be done as a patch but since llvm3.inc already +# manipulates this file with sed we have to do similar. We also need +# to do this as an append to ensure proper sequencing. +do_configure_append_x86-64() { + # Fix paths in llvm-config + sed -ri "s#lib/${LLVM_DIR}#lib64/${LLVM_DIR}#g" ${S}/tools/llvm-config/llvm-config.cpp +} + +# +# Override the do_install() provided by llvm3.inc to use the lib64 +# directory naming. +# +# This should probably be cleaned up at some point in the stock LLVM +# sources but at the moment they do not appear to handle lib64 very well. +# +do_install() { + cd ${LLVM_BUILD_DIR} + oe_runmake DESTDIR=${LLVM_INSTALL_DIR} install + + mv ${LLVM_INSTALL_DIR}${bindir}/${HOST_SYS}-llvm-config-host ${LLVM_INSTALL_DIR}/llvm-config-host + + install -d ${D}${bindir}/${LLVM_DIR} + mv ${LLVM_INSTALL_DIR}${bindir}/* ${D}${bindir}/${LLVM_DIR}/ + + install -d ${D}${includedir}/${LLVM_DIR} + mv ${LLVM_INSTALL_DIR}${includedir}/* ${D}${includedir}/${LLVM_DIR}/ + + install -d ${D}${libdir}/${LLVM_DIR} + + # The LLVM sources have "/lib" embedded and so we cannot completely rely on the ${libdir} variable + if [ -d ${LLVM_INSTALL_DIR}${libdir}/ ]; then + mv ${LLVM_INSTALL_DIR}${libdir}/* ${D}${libdir}/${LLVM_DIR}/ + elif [ -d ${LLVM_INSTALL_DIR}${prefix}/lib ]; then + mv ${LLVM_INSTALL_DIR}${prefix}/lib/* ${D}${libdir}/${LLVM_DIR}/ + elif [ -d ${LLVM_INSTALL_DIR}${prefix}/lib64 ]; then + mv ${LLVM_INSTALL_DIR}${prefix}/lib64/* ${D}${libdir}/${LLVM_DIR}/ + fi + + ln -s ${LLVM_DIR}/libLLVM-${PV}.so ${D}${libdir}/libLLVM-${PV}.so + + install -d ${D}${docdir}/${LLVM_DIR} + mv ${LLVM_INSTALL_DIR}${prefix}/docs/llvm/* ${D}${docdir}/${LLVM_DIR} +} diff --git a/meta-steppeeagle/recipes-core/llvm/llvm3.4/0001-R600-SI-Add-processor-type-for-Mullins.patch b/meta-steppeeagle/recipes-core/llvm/llvm3.4/0001-R600-SI-Add-processor-type-for-Mullins.patch new file mode 100644 index 00000000..d267c29a --- /dev/null +++ b/meta-steppeeagle/recipes-core/llvm/llvm3.4/0001-R600-SI-Add-processor-type-for-Mullins.patch @@ -0,0 +1,12 @@ +R600/SI: Add processor type for Mullins. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +diff -Naur a/lib/Target/R600/Processors.td b/lib/Target/R600/Processors.td +--- a/lib/Target/R600/Processors.td 2013-11-15 05:16:00.000000000 +0530 ++++ b/lib/Target/R600/Processors.td 2014-04-26 01:22:39.105011843 +0530 +@@ -52,3 +52,4 @@ + def : Proc<"kabini", SI_Itin, [FeatureSeaIslands]>; + def : Proc<"kaveri", SI_Itin, [FeatureSeaIslands]>; + def : Proc<"hawaii", SI_Itin, [FeatureSeaIslands]>; ++def : Proc<"mullins", SI_Itin, [FeatureSeaIslands]>; diff --git a/meta-steppeeagle/recipes-core/llvm/llvm3.4/arm_fenv_uclibc.patch b/meta-steppeeagle/recipes-core/llvm/llvm3.4/arm_fenv_uclibc.patch new file mode 100644 index 00000000..c3ae4946 --- /dev/null +++ b/meta-steppeeagle/recipes-core/llvm/llvm3.4/arm_fenv_uclibc.patch @@ -0,0 +1,14 @@ +Index: llvm-2.9/include/llvm/Support/FEnv.h +=================================================================== +--- llvm-2.9.orig/include/llvm/Support/FEnv.h 2010-11-29 20:44:50.000000000 +0100 ++++ llvm-2.9/include/llvm/Support/FEnv.h 2011-11-18 18:42:22.580161297 +0100 +@@ -17,6 +17,9 @@ + + #include "llvm/Config/config.h" + #include <cerrno> ++ ++#undef HAVE_FENV_H ++ + #ifdef HAVE_FENV_H + #include <fenv.h> + #endif diff --git a/meta-steppeeagle/recipes-core/llvm/llvm3.4_3.4.bb b/meta-steppeeagle/recipes-core/llvm/llvm3.4_3.4.bb new file mode 100644 index 00000000..e59f508a --- /dev/null +++ b/meta-steppeeagle/recipes-core/llvm/llvm3.4_3.4.bb @@ -0,0 +1,19 @@ +require recipes-core/llvm/llvm.inc +require recipes-core/llvm/llvm3.inc +require llvm3.4.inc + +LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=71df953c321b5b31ae94316a7fb6a7f3" + +DEPENDS += "zlib" +EXTRA_OECONF += "--enable-zlib" + +S = "${WORKDIR}/llvm-${PV}" + +SRC_URI += "file://0001-R600-SI-Add-processor-type-for-Mullins.patch" + +SRC_URI_append_libc-uclibc = " file://arm_fenv_uclibc.patch " +SRC_URI[md5sum] = "46ed668a1ce38985120dbf6344cf6116" +SRC_URI[sha256sum] = "25a5612d692c48481b9b397e2b55f4870e447966d66c96d655241702d44a2628" + +PACKAGECONFIG ??= "" +PACKAGECONFIG[r600] = "--enable-experimental-targets=R600,,," diff --git a/meta-steppeeagle/recipes-core/llvm/llvm3.4_3.4.bbappend b/meta-steppeeagle/recipes-core/llvm/llvm3.4_3.4.bbappend new file mode 100644 index 00000000..e648dcab --- /dev/null +++ b/meta-steppeeagle/recipes-core/llvm/llvm3.4_3.4.bbappend @@ -0,0 +1 @@ +PACKAGECONFIG_append_steppeeagle = "r600" diff --git a/meta-steppeeagle/recipes-graphics/drm/libdrm/0001-radeon-add-Mullins-chip-family.patch b/meta-steppeeagle/recipes-graphics/drm/libdrm/0001-radeon-add-Mullins-chip-family.patch new file mode 100644 index 00000000..97f9c354 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/drm/libdrm/0001-radeon-add-Mullins-chip-family.patch @@ -0,0 +1,26 @@ +From 0ca3b79c21c1db04d442b09654e4cc2d7d956276 Mon Sep 17 00:00:00 2001 +From: Samuel Li <samuel.li@amd.com> +Date: Thu, 17 Apr 2014 14:30:08 -0400 +Subject: [PATCH 1/2] radeon: add Mullins chip family + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + radeon/radeon_surface.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/radeon/radeon_surface.c b/radeon/radeon_surface.c +index 15127d4..109bd6b 100644 +--- a/radeon/radeon_surface.c ++++ b/radeon/radeon_surface.c +@@ -80,6 +80,7 @@ enum radeon_family { + CHIP_KAVERI, + CHIP_KABINI, + CHIP_HAWAII, ++ CHIP_MULLINS, + CHIP_LAST, + }; + +-- +1.8.3.1 + diff --git a/meta-steppeeagle/recipes-graphics/drm/libdrm/0002-radeon-add-Mullins-pci-ids.patch b/meta-steppeeagle/recipes-graphics/drm/libdrm/0002-radeon-add-Mullins-pci-ids.patch new file mode 100644 index 00000000..c5a22269 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/drm/libdrm/0002-radeon-add-Mullins-pci-ids.patch @@ -0,0 +1,42 @@ +From 532a41b72641791df14f3a7b49f6b9ebd9fe5022 Mon Sep 17 00:00:00 2001 +From: Samuel Li <samuel.li@amd.com> +Date: Tue, 12 Nov 2013 15:39:31 -0500 +Subject: [PATCH 2/2] radeon: add Mullins pci ids + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + radeon/r600_pci_ids.h | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/radeon/r600_pci_ids.h b/radeon/r600_pci_ids.h +index 37fb61c..de25f16 100644 +--- a/radeon/r600_pci_ids.h ++++ b/radeon/r600_pci_ids.h +@@ -425,6 +425,23 @@ CHIPSET(0x983D, KABINI_983D, KABINI) + CHIPSET(0x983E, KABINI_983E, KABINI) + CHIPSET(0x983F, KABINI_983F, KABINI) + ++CHIPSET(0x9850, MULLINS_9850, MULLINS) ++CHIPSET(0x9851, MULLINS_9851, MULLINS) ++CHIPSET(0x9852, MULLINS_9852, MULLINS) ++CHIPSET(0x9853, MULLINS_9853, MULLINS) ++CHIPSET(0x9854, MULLINS_9854, MULLINS) ++CHIPSET(0x9855, MULLINS_9855, MULLINS) ++CHIPSET(0x9856, MULLINS_9856, MULLINS) ++CHIPSET(0x9857, MULLINS_9857, MULLINS) ++CHIPSET(0x9858, MULLINS_9858, MULLINS) ++CHIPSET(0x9859, MULLINS_9859, MULLINS) ++CHIPSET(0x985A, MULLINS_985A, MULLINS) ++CHIPSET(0x985B, MULLINS_985B, MULLINS) ++CHIPSET(0x985C, MULLINS_985C, MULLINS) ++CHIPSET(0x985D, MULLINS_985D, MULLINS) ++CHIPSET(0x985E, MULLINS_985E, MULLINS) ++CHIPSET(0x985F, MULLINS_985F, MULLINS) ++ + CHIPSET(0x1304, KAVERI_1304, KAVERI) + CHIPSET(0x1305, KAVERI_1305, KAVERI) + CHIPSET(0x1306, KAVERI_1306, KAVERI) +-- +1.8.3.1 + diff --git a/meta-steppeeagle/recipes-graphics/drm/libdrm_git.bbappend b/meta-steppeeagle/recipes-graphics/drm/libdrm_git.bbappend new file mode 100644 index 00000000..cb5ebffd --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/drm/libdrm_git.bbappend @@ -0,0 +1,18 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +SRCREV = "e6ec4c88519da05eccc05ed2ae7ff20277e3672a" +PV = "2.4.53+git${SRCPV}" + +SRC_URI += " \ + file://0001-radeon-add-Mullins-chip-family.patch \ + file://0002-radeon-add-Mullins-pci-ids.patch \ + " + +PATCHTOOL = "git" + +EXTRA_OECONF += "--enable-optimized \ + --disable-assertions \ + --enable-shared \ + --enable-targets=x86_64 \ + --enable-experimental-targets=R600 \ + --enable-bindings=none" diff --git a/meta-steppeeagle/recipes-graphics/mesa-demos/mesa-demos/0001-mesa-demos-Add-missing-data-files.patch b/meta-steppeeagle/recipes-graphics/mesa-demos/mesa-demos/0001-mesa-demos-Add-missing-data-files.patch new file mode 100644 index 00000000..c7851035 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/mesa-demos/mesa-demos/0001-mesa-demos-Add-missing-data-files.patch @@ -0,0 +1,623 @@ +From 87f9a62329d7c5f4d351fbb63a41f2a1935fb2f1 Mon Sep 17 00:00:00 2001 +From: Drew Moseley <drew_moseley@mentor.com> +Date: Mon, 12 May 2014 15:22:32 -0400 +Subject: [PATCH] mesa-demos: Add missing data files. + +Add some data files that are present in the git repository: + http://cgit.freedesktop.org/mesa/demos/tree/?id=mesa-demos-8.1.0 +but not in the release tarball + ftp://ftp.freedesktop.org/pub/mesa/demos/8.1.0/mesa-demos-8.1.0.tar.bz2 + +Upstream-Status: Backport +Signed-off-by: Drew Moseley <drew_moseley@mentor.com> +--- + src/fpglsl/depth-read.glsl | 4 + + src/fpglsl/infinite-loop.glsl | 7 + + src/glsl/CH11-bumpmaptex.frag | 47 +++++++ + src/glsl/blinking-teapot.frag | 31 +++++ + src/glsl/blinking-teapot.vert | 16 +++ + src/glsl/convolution.frag | 21 +++ + src/glsl/simplex-noise.glsl | 279 +++++++++++++++++++++++++++++++++++++++ + src/glsl/skinning.vert | 24 ++++ + src/perf/glslstateschange1.frag | 19 +++ + src/perf/glslstateschange1.vert | 14 ++ + src/perf/glslstateschange2.frag | 17 +++ + src/perf/glslstateschange2.vert | 14 ++ + src/vpglsl/infinite-loop.glsl | 8 ++ + 13 files changed, 501 insertions(+) + create mode 100644 src/fpglsl/depth-read.glsl + create mode 100644 src/fpglsl/infinite-loop.glsl + create mode 100644 src/glsl/CH11-bumpmaptex.frag + create mode 100644 src/glsl/blinking-teapot.frag + create mode 100644 src/glsl/blinking-teapot.vert + create mode 100644 src/glsl/convolution.frag + create mode 100644 src/glsl/simplex-noise.glsl + create mode 100644 src/glsl/skinning.vert + create mode 100644 src/perf/glslstateschange1.frag + create mode 100644 src/perf/glslstateschange1.vert + create mode 100644 src/perf/glslstateschange2.frag + create mode 100644 src/perf/glslstateschange2.vert + create mode 100644 src/vpglsl/infinite-loop.glsl + +diff --git a/src/fpglsl/depth-read.glsl b/src/fpglsl/depth-read.glsl +new file mode 100644 +index 0000000..86d298e +--- /dev/null ++++ b/src/fpglsl/depth-read.glsl +@@ -0,0 +1,4 @@ ++void main() ++{ ++ gl_FragColor = gl_FragCoord.zzzz; ++} +diff --git a/src/fpglsl/infinite-loop.glsl b/src/fpglsl/infinite-loop.glsl +new file mode 100644 +index 0000000..c6dc6ee +--- /dev/null ++++ b/src/fpglsl/infinite-loop.glsl +@@ -0,0 +1,7 @@ ++void main() { ++ vec4 sum = vec4(0); ++ for (int i = 1; i != 2; i += 2) { ++ sum += vec4(0.1, 0.1, 0.1, 0.1); ++ } ++ gl_FragColor = sum; ++} +diff --git a/src/glsl/CH11-bumpmaptex.frag b/src/glsl/CH11-bumpmaptex.frag +new file mode 100644 +index 0000000..b5dabb4 +--- /dev/null ++++ b/src/glsl/CH11-bumpmaptex.frag +@@ -0,0 +1,47 @@ ++// ++// Fragment shader for procedural bumps ++// ++// Authors: John Kessenich, Randi Rost ++// ++// Copyright (c) 2002-2006 3Dlabs Inc. Ltd. ++// ++// See 3Dlabs-License.txt for license information ++// ++// Texture mapping/modulation added by Brian Paul ++// ++ ++varying vec3 LightDir; ++varying vec3 EyeDir; ++ ++uniform float BumpDensity; // = 16.0 ++uniform float BumpSize; // = 0.15 ++uniform float SpecularFactor; // = 0.5 ++ ++uniform sampler2D Tex; ++ ++void main() ++{ ++ vec3 ambient = vec3(0.25); ++ vec3 litColor; ++ vec2 c = BumpDensity * gl_TexCoord[0].st; ++ vec2 p = fract(c) - vec2(0.5); ++ ++ float d, f; ++ d = p.x * p.x + p.y * p.y; ++ f = inversesqrt(d + 1.0); ++ ++ if (d >= BumpSize) ++ { p = vec2(0.0); f = 1.0; } ++ ++ vec3 SurfaceColor = texture2D(Tex, gl_TexCoord[0].st).xyz; ++ ++ vec3 normDelta = vec3(p.x, p.y, 1.0) * f; ++ litColor = SurfaceColor * (ambient + max(dot(normDelta, LightDir), 0.0)); ++ vec3 reflectDir = reflect(LightDir, normDelta); ++ ++ float spec = max(dot(EyeDir, reflectDir), 0.0); ++ spec *= SpecularFactor; ++ litColor = min(litColor + spec, vec3(1.0)); ++ ++ gl_FragColor = vec4(litColor, 1.0); ++} +diff --git a/src/glsl/blinking-teapot.frag b/src/glsl/blinking-teapot.frag +new file mode 100644 +index 0000000..0db060b +--- /dev/null ++++ b/src/glsl/blinking-teapot.frag +@@ -0,0 +1,31 @@ ++#extension GL_ARB_uniform_buffer_object : enable ++ ++layout(std140) uniform colors0 ++{ ++ float DiffuseCool; ++ float DiffuseWarm; ++ vec3 SurfaceColor; ++ vec3 WarmColor; ++ vec3 CoolColor; ++ vec4 some[8]; ++}; ++ ++varying float NdotL; ++varying vec3 ReflectVec; ++varying vec3 ViewVec; ++ ++void main (void) ++{ ++ ++ vec3 kcool = min(CoolColor + DiffuseCool * SurfaceColor, 1.0); ++ vec3 kwarm = min(WarmColor + DiffuseWarm * SurfaceColor, 1.0); ++ vec3 kfinal = mix(kcool, kwarm, NdotL); ++ ++ vec3 nreflect = normalize(ReflectVec); ++ vec3 nview = normalize(ViewVec); ++ ++ float spec = max(dot(nreflect, nview), 0.0); ++ spec = pow(spec, 32.0); ++ ++ gl_FragColor = vec4 (min(kfinal + spec, 1.0), 1.0); ++} +diff --git a/src/glsl/blinking-teapot.vert b/src/glsl/blinking-teapot.vert +new file mode 100644 +index 0000000..397d733 +--- /dev/null ++++ b/src/glsl/blinking-teapot.vert +@@ -0,0 +1,16 @@ ++vec3 LightPosition = vec3(0.0, 10.0, 4.0); ++ ++varying float NdotL; ++varying vec3 ReflectVec; ++varying vec3 ViewVec; ++ ++void main(void) ++{ ++ vec3 ecPos = vec3 (gl_ModelViewMatrix * gl_Vertex); ++ vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal); ++ vec3 lightVec = normalize(LightPosition - ecPos); ++ ReflectVec = normalize(reflect(-lightVec, tnorm)); ++ ViewVec = normalize(-ecPos); ++ NdotL = (dot(lightVec, tnorm) + 1.0) * 0.5; ++ gl_Position = ftransform(); ++} +diff --git a/src/glsl/convolution.frag b/src/glsl/convolution.frag +new file mode 100644 +index 0000000..e49b8ac +--- /dev/null ++++ b/src/glsl/convolution.frag +@@ -0,0 +1,21 @@ ++ ++const int KernelSize = 9; ++ ++//texture offsets ++uniform vec2 Offset[KernelSize]; ++//convolution kernel ++uniform vec4 KernelValue[KernelSize]; ++uniform sampler2D srcTex; ++uniform vec4 ScaleFactor; ++uniform vec4 BaseColor; ++ ++void main(void) ++{ ++ int i; ++ vec4 sum = vec4(0.0); ++ for (i = 0; i < KernelSize; ++i) { ++ vec4 tmp = texture2D(srcTex, gl_TexCoord[0].st + Offset[i]); ++ sum += tmp * KernelValue[i]; ++ } ++ gl_FragColor = sum * ScaleFactor + BaseColor; ++} +diff --git a/src/glsl/simplex-noise.glsl b/src/glsl/simplex-noise.glsl +new file mode 100644 +index 0000000..b6833cb +--- /dev/null ++++ b/src/glsl/simplex-noise.glsl +@@ -0,0 +1,279 @@ ++// ++// Description : Array and textureless GLSL 2D/3D/4D simplex ++// noise functions. ++// Author : Ian McEwan, Ashima Arts. ++// Maintainer : ijm ++// Lastmod : 20110223 ++// License : Copyright (C) 2011 Ashima Arts. All rights reserved. ++// Distributed under the Artistic License 2.0; See LICENCE file. ++// ++ ++#define NORMALIZE_GRADIENTS ++#undef USE_CIRCLE ++#define COLLAPSE_SORTNET ++ ++float permute(float x0,vec3 p) { ++ float x1 = mod(x0 * p.y, p.x); ++ return floor( mod( (x1 + p.z) *x0, p.x )); ++ } ++vec2 permute(vec2 x0,vec3 p) { ++ vec2 x1 = mod(x0 * p.y, p.x); ++ return floor( mod( (x1 + p.z) *x0, p.x )); ++ } ++vec3 permute(vec3 x0,vec3 p) { ++ vec3 x1 = mod(x0 * p.y, p.x); ++ return floor( mod( (x1 + p.z) *x0, p.x )); ++ } ++vec4 permute(vec4 x0,vec3 p) { ++ vec4 x1 = mod(x0 * p.y, p.x); ++ return floor( mod( (x1 + p.z) *x0, p.x )); ++ } ++ ++uniform vec4 pParam; ++// Example ++// const vec4 pParam = vec4( 17.* 17., 34., 1., 7.); ++ ++float taylorInvSqrt(float r) ++ { ++ return ( 0.83666002653408 + 0.7*0.85373472095314 - 0.85373472095314 * r ); ++ } ++ ++float simplexNoise2(vec2 v) ++ { ++ const vec2 C = vec2(0.211324865405187134, // (3.0-sqrt(3.0))/6.; ++ 0.366025403784438597); // 0.5*(sqrt(3.0)-1.); ++ const vec3 D = vec3( 0., 0.5, 2.0) * 3.14159265358979312; ++// First corner ++ vec2 i = floor(v + dot(v, C.yy) ); ++ vec2 x0 = v - i + dot(i, C.xx); ++ ++// Other corners ++ vec2 i1 = (x0.x > x0.y) ? vec2(1.,0.) : vec2(0.,1.) ; ++ ++ // x0 = x0 - 0. + 0. * C ++ vec2 x1 = x0 - i1 + 1. * C.xx ; ++ vec2 x2 = x0 - 1. + 2. * C.xx ; ++ ++// Permutations ++ i = mod(i, pParam.x); ++ vec3 p = permute( permute( ++ i.y + vec3(0., i1.y, 1. ), pParam.xyz) ++ + i.x + vec3(0., i1.x, 1. ), pParam.xyz); ++ ++#ifndef USE_CIRCLE ++// ( N points uniformly over a line, mapped onto a diamond.) ++ vec3 x = fract(p / pParam.w) ; ++ vec3 h = 0.5 - abs(x) ; ++ ++ vec3 sx = vec3(lessThan(x,D.xxx)) *2. -1.; ++ vec3 sh = vec3(lessThan(h,D.xxx)); ++ ++ vec3 a0 = x + sx*sh; ++ vec2 p0 = vec2(a0.x,h.x); ++ vec2 p1 = vec2(a0.y,h.y); ++ vec2 p2 = vec2(a0.z,h.z); ++ ++#ifdef NORMALISE_GRADIENTS ++ p0 *= taylorInvSqrt(dot(p0,p0)); ++ p1 *= taylorInvSqrt(dot(p1,p1)); ++ p2 *= taylorInvSqrt(dot(p2,p2)); ++#endif ++ ++ vec3 g = 2.0 * vec3( dot(p0, x0), dot(p1, x1), dot(p2, x2) ); ++#else ++// N points around a unit circle. ++ vec3 phi = D.z * mod(p,pParam.w) /pParam.w ; ++ vec4 a0 = sin(phi.xxyy+D.xyxy); ++ vec2 a1 = sin(phi.zz +D.xy); ++ vec3 g = vec3( dot(a0.xy, x0), dot(a0.zw, x1), dot(a1.xy, x2) ); ++#endif ++// mix ++ vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.); ++ m = m*m ; ++ return 1.66666* 70.*dot(m*m, g); ++ } ++ ++float simplexNoise3(vec3 v) ++ { ++ const vec2 C = vec2(1./6. , 1./3. ) ; ++ const vec4 D = vec4(0., 0.5, 1.0, 2.0); ++ ++// First corner ++ vec3 i = floor(v + dot(v, C.yyy) ); ++ vec3 x0 = v - i + dot(i, C.xxx) ; ++ ++// Other corners ++#ifdef COLLAPSE_SORTNET ++ vec3 g = vec3( greaterThan( x0.xyz, x0.yzx) ); ++ vec3 l = vec3( lessThanEqual( x0.xyz, x0.yzx) ); ++ ++ vec3 i1 = g.xyz * l.zxy; ++ vec3 i2 = max( g.xyz, l.zxy); ++#else ++// Keeping this clean - let the compiler optimize. ++ vec3 q1; ++ q1.x = max(x0.x, x0.y); ++ q1.y = min(x0.x, x0.y); ++ q1.z = x0.z; ++ ++ vec3 q2; ++ q2.x = max(q1.x,q1.z); ++ q2.z = min(q1.x,q1.z); ++ q2.y = q1.y; ++ ++ vec3 q3; ++ q3.y = max(q2.y, q2.z); ++ q3.z = min(q2.y, q2.z); ++ q3.x = q2.x; ++ ++ vec3 i1 = vec3(equal(q3.xxx, x0)); ++ vec3 i2 = i1 + vec3(equal(q3.yyy, x0)); ++#endif ++ ++ // x0 = x0 - 0. + 0. * C ++ vec3 x1 = x0 - i1 + 1. * C.xxx; ++ vec3 x2 = x0 - i2 + 2. * C.xxx; ++ vec3 x3 = x0 - 1. + 3. * C.xxx; ++ ++// Permutations ++ i = mod(i, pParam.x ); ++ vec4 p = permute( permute( permute( ++ i.z + vec4(0., i1.z, i2.z, 1. ), pParam.xyz) ++ + i.y + vec4(0., i1.y, i2.y, 1. ), pParam.xyz) ++ + i.x + vec4(0., i1.x, i2.x, 1. ), pParam.xyz); ++ ++// Gradients ++// ( N*N points uniformly over a square, mapped onto a octohedron.) ++ float n_ = 1.0/pParam.w ; ++ vec3 ns = n_ * D.wyz - D.xzx ; ++ ++ vec4 j = p - pParam.w*pParam.w*floor(p * ns.z *ns.z); // mod(p,N*N) ++ ++ vec4 x_ = floor(j * ns.z) ; ++ vec4 y_ = floor(j - pParam.w * x_ ) ; // mod(j,N) ++ ++ vec4 x = x_ *ns.x + ns.yyyy; ++ vec4 y = y_ *ns.x + ns.yyyy; ++ vec4 h = 1. - abs(x) - abs(y); ++ ++ vec4 b0 = vec4( x.xy, y.xy ); ++ vec4 b1 = vec4( x.zw, y.zw ); ++ ++ vec4 s0 = vec4(lessThan(b0,D.xxxx)) *2. -1.; ++ vec4 s1 = vec4(lessThan(b1,D.xxxx)) *2. -1.; ++ vec4 sh = vec4(lessThan(h, D.xxxx)); ++ ++ vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; ++ vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; ++ ++ vec3 p0 = vec3(a0.xy,h.x); ++ vec3 p1 = vec3(a0.zw,h.y); ++ vec3 p2 = vec3(a1.xy,h.z); ++ vec3 p3 = vec3(a1.zw,h.w); ++ ++#ifdef NORMALISE_GRADIENTS ++ p0 *= taylorInvSqrt(dot(p0,p0)); ++ p1 *= taylorInvSqrt(dot(p1,p1)); ++ p2 *= taylorInvSqrt(dot(p2,p2)); ++ p3 *= taylorInvSqrt(dot(p3,p3)); ++#endif ++ ++// Mix ++ vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.); ++ m = m * m; ++//used to be 64. ++ return 48.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), ++ dot(p2,x2), dot(p3,x3) ) ); ++ } ++ ++vec4 grad4(float j, vec4 ip) ++ { ++ const vec4 ones = vec4(1.,1.,1.,-1.); ++ vec4 p,s; ++ ++ p.xyz = floor( fract (vec3(j) * ip.xyz) *pParam.w) * ip.z -1.0; ++ p.w = 1.5 - dot(abs(p.xyz), ones.xyz); ++ s = vec4(lessThan(p,vec4(0.))); ++ p.xyz = p.xyz + (s.xyz*2.-1.) * s.www; ++ ++ return p; ++ } ++ ++float simplexNoise4(vec4 v) ++ { ++ const vec2 C = vec2( 0.138196601125010504, // (5 - sqrt(5))/20 G4 ++ 0.309016994374947451); // (sqrt(5) - 1)/4 F4 ++// First corner ++ vec4 i = floor(v + dot(v, C.yyyy) ); ++ vec4 x0 = v - i + dot(i, C.xxxx); ++ ++// Other corners ++ ++// Force existance of strict total ordering in sort. ++ vec4 q0 = floor(x0 * 1024.0) + vec4( 0., 1./4., 2./4. , 3./4.); ++ vec4 q1; ++ q1.xy = max(q0.xy,q0.zw); // x:z y:w ++ q1.zw = min(q0.xy,q0.zw); ++ ++ vec4 q2; ++ q2.xz = max(q1.xz,q1.yw); // x:y z:w ++ q2.yw = min(q1.xz,q1.yw); ++ ++ vec4 q3; ++ q3.y = max(q2.y,q2.z); // y:z ++ q3.z = min(q2.y,q2.z); ++ q3.xw = q2.xw; ++ ++ vec4 i1 = vec4(lessThanEqual(q3.xxxx, q0)); ++ vec4 i2 = vec4(lessThanEqual(q3.yyyy, q0)); ++ vec4 i3 = vec4(lessThanEqual(q3.zzzz, q0)); ++ ++ // x0 = x0 - 0. + 0. * C ++ vec4 x1 = x0 - i1 + 1. * C.xxxx; ++ vec4 x2 = x0 - i2 + 2. * C.xxxx; ++ vec4 x3 = x0 - i3 + 3. * C.xxxx; ++ vec4 x4 = x0 - 1. + 4. * C.xxxx; ++ ++// Permutations ++ i = mod(i, pParam.x ); ++ float j0 = permute( permute( permute( permute ( ++ i.w, pParam.xyz) + i.z, pParam.xyz) ++ + i.y, pParam.xyz) + i.x, pParam.xyz); ++ vec4 j1 = permute( permute( permute( permute ( ++ i.w + vec4(i1.w, i2.w, i3.w, 1. ), pParam.xyz) ++ + i.z + vec4(i1.z, i2.z, i3.z, 1. ), pParam.xyz) ++ + i.y + vec4(i1.y, i2.y, i3.y, 1. ), pParam.xyz) ++ + i.x + vec4(i1.x, i2.x, i3.x, 1. ), pParam.xyz); ++// Gradients ++// ( N*N*N points uniformly over a cube, mapped onto a 4-octohedron.) ++ vec4 ip = pParam ; ++ ip.xy *= pParam.w ; ++ ip.x *= pParam.w ; ++ ip = vec4(1.,1.,1.,2.) / ip ; ++ ++ vec4 p0 = grad4(j0, ip); ++ vec4 p1 = grad4(j1.x, ip); ++ vec4 p2 = grad4(j1.y, ip); ++ vec4 p3 = grad4(j1.z, ip); ++ vec4 p4 = grad4(j1.w, ip); ++ ++#ifdef NORMALISE_GRADIENTS ++ p0 *= taylorInvSqrt(dot(p0,p0)); ++ p1 *= taylorInvSqrt(dot(p1,p1)); ++ p2 *= taylorInvSqrt(dot(p2,p2)); ++ p3 *= taylorInvSqrt(dot(p3,p3)); ++ p4 *= taylorInvSqrt(dot(p4,p4)); ++#endif ++ ++// Mix ++ vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.); ++ vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.); ++ m0 = m0 * m0; ++ m1 = m1 * m1; ++ return 32. * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 ))) ++ + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ; ++ ++ } ++ ++ ++ +diff --git a/src/glsl/skinning.vert b/src/glsl/skinning.vert +new file mode 100644 +index 0000000..28970ee +--- /dev/null ++++ b/src/glsl/skinning.vert +@@ -0,0 +1,24 @@ ++// Vertex weighting/blendin shader ++// Brian Paul ++// 4 Nov 2008 ++ ++uniform mat4 mat0, mat1; ++attribute float weight; ++ ++void main() ++{ ++ // simple diffuse shading ++ // Note that we should really transform the normal vector along with ++ // the postion below... someday. ++ vec3 lightVec = vec3(0, 0, 1); ++ vec3 norm = gl_NormalMatrix * gl_Normal; ++ float dot = 0.2 + max(0.0, dot(norm, lightVec)); ++ gl_FrontColor = vec4(dot); ++ ++ // compute sum of weighted transformations ++ vec4 pos0 = mat0 * gl_Vertex; ++ vec4 pos1 = mat1 * gl_Vertex; ++ vec4 pos = mix(pos0, pos1, weight); ++ ++ gl_Position = gl_ModelViewProjectionMatrix * pos; ++} +diff --git a/src/perf/glslstateschange1.frag b/src/perf/glslstateschange1.frag +new file mode 100644 +index 0000000..0839436 +--- /dev/null ++++ b/src/perf/glslstateschange1.frag +@@ -0,0 +1,19 @@ ++// Multi-texture fragment shader ++// Brian Paul ++ ++// Composite second texture over first. ++// We're assuming the 2nd texture has a meaningful alpha channel. ++ ++uniform sampler2D tex1; ++uniform sampler2D tex2; ++uniform vec4 UniV1; ++uniform vec4 UniV2; ++ ++void main() ++{ ++ vec4 t3; ++ vec4 t1 = texture2D(tex1, gl_TexCoord[0].xy); ++ vec4 t2 = texture2D(tex2, gl_TexCoord[1].xy); ++ t3 = mix(t1, t2, t2.w); ++ gl_FragColor = t3 + UniV1 + UniV2; ++} +diff --git a/src/perf/glslstateschange1.vert b/src/perf/glslstateschange1.vert +new file mode 100644 +index 0000000..cef50db +--- /dev/null ++++ b/src/perf/glslstateschange1.vert +@@ -0,0 +1,14 @@ ++// Multi-texture vertex shader ++// Brian Paul ++ ++ ++attribute vec4 TexCoord0, TexCoord1; ++attribute vec4 VertCoord; ++ ++void main() ++{ ++ gl_TexCoord[0] = TexCoord0; ++ gl_TexCoord[1] = TexCoord1; ++ // note: may use gl_Vertex or VertCoord here for testing: ++ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; ++} +diff --git a/src/perf/glslstateschange2.frag b/src/perf/glslstateschange2.frag +new file mode 100644 +index 0000000..0df0319 +--- /dev/null ++++ b/src/perf/glslstateschange2.frag +@@ -0,0 +1,17 @@ ++// Multi-texture fragment shader ++// Brian Paul ++ ++// Composite second texture over first. ++// We're assuming the 2nd texture has a meaningful alpha channel. ++ ++uniform sampler2D tex1; ++uniform sampler2D tex2; ++uniform vec4 UniV1; ++uniform vec4 UniV2; ++ ++void main() ++{ ++ vec4 t1 = texture2D(tex1, gl_TexCoord[0].xy); ++ vec4 t2 = texture2D(tex2, gl_TexCoord[1].xy); ++ gl_FragColor = t1 + t2 + UniV1 + UniV2; ++} +diff --git a/src/perf/glslstateschange2.vert b/src/perf/glslstateschange2.vert +new file mode 100644 +index 0000000..cef50db +--- /dev/null ++++ b/src/perf/glslstateschange2.vert +@@ -0,0 +1,14 @@ ++// Multi-texture vertex shader ++// Brian Paul ++ ++ ++attribute vec4 TexCoord0, TexCoord1; ++attribute vec4 VertCoord; ++ ++void main() ++{ ++ gl_TexCoord[0] = TexCoord0; ++ gl_TexCoord[1] = TexCoord1; ++ // note: may use gl_Vertex or VertCoord here for testing: ++ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; ++} +diff --git a/src/vpglsl/infinite-loop.glsl b/src/vpglsl/infinite-loop.glsl +new file mode 100644 +index 0000000..bc7ae4b +--- /dev/null ++++ b/src/vpglsl/infinite-loop.glsl +@@ -0,0 +1,8 @@ ++void main() { ++ gl_Position = gl_Vertex; ++ vec4 sum = vec4(0); ++ for (int i = 1; i != 2; i += 2) { ++ sum += vec4(0.1, 0.1, 0.1, 0.1); ++ } ++ gl_FrontColor = sum; ++} +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-graphics/mesa-demos/mesa-demos/0001-mesa-demos-Use-DEMOS_DATA_DIR-to-locate-data-files.patch b/meta-steppeeagle/recipes-graphics/mesa-demos/mesa-demos/0001-mesa-demos-Use-DEMOS_DATA_DIR-to-locate-data-files.patch new file mode 100644 index 00000000..c89f8789 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/mesa-demos/mesa-demos/0001-mesa-demos-Use-DEMOS_DATA_DIR-to-locate-data-files.patch @@ -0,0 +1,234 @@ +From bc7fa67d13e8032601df5cf04e15c53a7204dcd7 Mon Sep 17 00:00:00 2001 +From: Drew Moseley <drew_moseley@mentor.com> +Date: Fri, 9 May 2014 11:50:24 -0400 +Subject: [PATCH] mesa-demos: Use DEMOS_DATA_DIR to locate data files + +Upstream-Status: Submitted [https://bugs.freedesktop.org/show_bug.cgi?id=78496] +Signed-off-by: Drew Moseley <drew_moseley@mentor.com> +--- + src/glsl/bezier.c | 2 +- + src/glsl/blinking-teapot.c | 4 ++-- + src/glsl/brick.c | 4 ++-- + src/glsl/bump.c | 6 +++--- + src/glsl/convolutions.c | 2 +- + src/glsl/mandelbrot.c | 4 ++-- + src/glsl/multitex.c | 4 ++-- + src/glsl/simplex-noise.c | 2 +- + src/glsl/skinning.c | 4 ++-- + src/glsl/texdemo1.c | 8 ++++---- + src/glsl/toyball.c | 4 ++-- + src/objviewer/objview.c | 12 ++++++------ + src/perf/glslstateschange.c | 8 ++++---- + 13 files changed, 32 insertions(+), 32 deletions(-) + +diff --git a/src/glsl/bezier.c b/src/glsl/bezier.c +index 0b56bc1..e01603d 100644 +--- a/src/glsl/bezier.c ++++ b/src/glsl/bezier.c +@@ -13,7 +13,7 @@ + #include "glut_wrap.h" + #include "shaderutil.h" + +-static const char *filename = "bezier.geom"; ++static const char *filename = DEMOS_DATA_DIR "bezier.geom"; + + static GLuint fragShader; + static GLuint vertShader; +diff --git a/src/glsl/blinking-teapot.c b/src/glsl/blinking-teapot.c +index e3bf24d..7662b1f 100644 +--- a/src/glsl/blinking-teapot.c ++++ b/src/glsl/blinking-teapot.c +@@ -63,8 +63,8 @@ init_opengl (void) + exit(1); + } + +- vshad_id = CompileShaderFile (GL_VERTEX_SHADER, "blinking-teapot.vert"); +- fshad_id = CompileShaderFile (GL_FRAGMENT_SHADER, "blinking-teapot.frag"); ++ vshad_id = CompileShaderFile (GL_VERTEX_SHADER, DEMOS_DATA_DIR "blinking-teapot.vert"); ++ fshad_id = CompileShaderFile (GL_FRAGMENT_SHADER, DEMOS_DATA_DIR "blinking-teapot.frag"); + prog_id = LinkShaders (vshad_id, fshad_id); + + UseProgram (prog_id); +diff --git a/src/glsl/brick.c b/src/glsl/brick.c +index 3021856..fe5f190 100644 +--- a/src/glsl/brick.c ++++ b/src/glsl/brick.c +@@ -14,8 +14,8 @@ + #include "shaderutil.h" + + +-static char *FragProgFile = "CH06-brick.frag"; +-static char *VertProgFile = "CH06-brick.vert"; ++static char *FragProgFile = DEMOS_DATA_DIR "CH06-brick.frag"; ++static char *VertProgFile = DEMOS_DATA_DIR "CH06-brick.vert"; + + /* program/shader objects */ + static GLuint fragShader; +diff --git a/src/glsl/bump.c b/src/glsl/bump.c +index 59f62cd..3a1b20a 100644 +--- a/src/glsl/bump.c ++++ b/src/glsl/bump.c +@@ -15,9 +15,9 @@ + #include "readtex.h" + + +-static char *FragProgFile = "CH11-bumpmap.frag"; +-static char *FragTexProgFile = "CH11-bumpmaptex.frag"; +-static char *VertProgFile = "CH11-bumpmap.vert"; ++static char *FragProgFile = DEMOS_DATA_DIR "CH11-bumpmap.frag"; ++static char *FragTexProgFile = DEMOS_DATA_DIR "CH11-bumpmaptex.frag"; ++static char *VertProgFile = DEMOS_DATA_DIR "CH11-bumpmap.vert"; + static char *TextureFile = DEMOS_DATA_DIR "tile.rgb"; + + /* program/shader objects */ +diff --git a/src/glsl/convolutions.c b/src/glsl/convolutions.c +index a120cfe..9312f00 100644 +--- a/src/glsl/convolutions.c ++++ b/src/glsl/convolutions.c +@@ -340,7 +340,7 @@ static void init(void) + + menuInit(); + readTexture(textureLocation); +- createProgram("convolution.vert", "convolution.frag"); ++ createProgram(DEMOS_DATA_DIR "convolution.vert", DEMOS_DATA_DIR "convolution.frag"); + + glEnable(GL_TEXTURE_2D); + glClearColor(1.0, 1.0, 1.0, 1.0); +diff --git a/src/glsl/mandelbrot.c b/src/glsl/mandelbrot.c +index 31ede1d..ab34a0f 100644 +--- a/src/glsl/mandelbrot.c ++++ b/src/glsl/mandelbrot.c +@@ -14,8 +14,8 @@ + #include "shaderutil.h" + + +-static char *FragProgFile = "CH18-mandel.frag"; +-static char *VertProgFile = "CH18-mandel.vert"; ++static char *FragProgFile = DEMOS_DATA_DIR "CH18-mandel.frag"; ++static char *VertProgFile = DEMOS_DATA_DIR "CH18-mandel.vert"; + + /* program/shader objects */ + static GLuint fragShader; +diff --git a/src/glsl/multitex.c b/src/glsl/multitex.c +index 262ea50..546bd27 100644 +--- a/src/glsl/multitex.c ++++ b/src/glsl/multitex.c +@@ -35,8 +35,8 @@ + + static const char *Demo = "multitex"; + +-static const char *VertFile = "multitex.vert"; +-static const char *FragFile = "multitex.frag"; ++static const char *VertFile = DEMOS_DATA_DIR "multitex.vert"; ++static const char *FragFile = DEMOS_DATA_DIR "multitex.frag"; + + static const char *TexFiles[2] = + { +diff --git a/src/glsl/simplex-noise.c b/src/glsl/simplex-noise.c +index 13fdd5d..885f01e 100644 +--- a/src/glsl/simplex-noise.c ++++ b/src/glsl/simplex-noise.c +@@ -169,7 +169,7 @@ SpecialKey(int key, int x, int y) + static void + Init(void) + { +- const char *filename = "simplex-noise.glsl"; ++ const char *filename = DEMOS_DATA_DIR "simplex-noise.glsl"; + char noiseText[10000]; + FILE *f; + int len; +diff --git a/src/glsl/skinning.c b/src/glsl/skinning.c +index bf38d77..536d475 100644 +--- a/src/glsl/skinning.c ++++ b/src/glsl/skinning.c +@@ -20,8 +20,8 @@ + #define M_PI 3.1415926535 + #endif + +-static char *FragProgFile = "skinning.frag"; +-static char *VertProgFile = "skinning.vert"; ++static char *FragProgFile = DEMOS_DATA_DIR "skinning.frag"; ++static char *VertProgFile = DEMOS_DATA_DIR "skinning.vert"; + + /* program/shader objects */ + static GLuint fragShader; +diff --git a/src/glsl/texdemo1.c b/src/glsl/texdemo1.c +index 6cde239..a082342 100644 +--- a/src/glsl/texdemo1.c ++++ b/src/glsl/texdemo1.c +@@ -35,11 +35,11 @@ + + static const char *Demo = "texdemo1"; + +-static const char *ReflectVertFile = "reflect.vert"; +-static const char *CubeFragFile = "cubemap.frag"; ++static const char *ReflectVertFile = DEMOS_DATA_DIR "reflect.vert"; ++static const char *CubeFragFile = DEMOS_DATA_DIR "cubemap.frag"; + +-static const char *SimpleVertFile = "simple.vert"; +-static const char *SimpleTexFragFile = "shadowtex.frag"; ++static const char *SimpleVertFile = DEMOS_DATA_DIR "simple.vert"; ++static const char *SimpleTexFragFile = DEMOS_DATA_DIR "shadowtex.frag"; + + static const char *GroundImage = DEMOS_DATA_DIR "tile.rgb"; + +diff --git a/src/glsl/toyball.c b/src/glsl/toyball.c +index 5f27951..4e7e832 100644 +--- a/src/glsl/toyball.c ++++ b/src/glsl/toyball.c +@@ -14,8 +14,8 @@ + #include "shaderutil.h" + + +-static char *FragProgFile = "CH11-toyball.frag"; +-static char *VertProgFile = "CH11-toyball.vert"; ++static char *FragProgFile = DEMOS_DATA_DIR "CH11-toyball.frag"; ++static char *VertProgFile = DEMOS_DATA_DIR "CH11-toyball.vert"; + + /* program/shader objects */ + static GLuint fragShader; +diff --git a/src/objviewer/objview.c b/src/objviewer/objview.c +index 6def726..78a6acf 100644 +--- a/src/objviewer/objview.c ++++ b/src/objviewer/objview.c +@@ -162,12 +162,12 @@ init_model(void) + static void + init_skybox(void) + { +- SkyboxTex = LoadSkyBoxCubeTexture("alpine_east.rgb", +- "alpine_west.rgb", +- "alpine_up.rgb", +- "alpine_down.rgb", +- "alpine_south.rgb", +- "alpine_north.rgb"); ++ SkyboxTex = LoadSkyBoxCubeTexture(DEMOS_DATA_DIR "alpine_east.rgb", ++ DEMOS_DATA_DIR "alpine_west.rgb", ++ DEMOS_DATA_DIR "alpine_up.rgb", ++ DEMOS_DATA_DIR "alpine_down.rgb", ++ DEMOS_DATA_DIR "alpine_south.rgb", ++ DEMOS_DATA_DIR "alpine_north.rgb"); + glmSpecularTexture(Model, SkyboxTex); + } + +diff --git a/src/perf/glslstateschange.c b/src/perf/glslstateschange.c +index 7422b78..dbf8332 100644 +--- a/src/perf/glslstateschange.c ++++ b/src/perf/glslstateschange.c +@@ -33,10 +33,10 @@ + #include "glmain.h" + #include "common.h" + +-static const char *VertFile1 = "glslstateschange1.vert"; +-static const char *FragFile1 = "glslstateschange1.frag"; +-static const char *VertFile2 = "glslstateschange2.vert"; +-static const char *FragFile2 = "glslstateschange2.frag"; ++static const char *VertFile1 = DEMOS_DATA_DIR "glslstateschange1.vert"; ++static const char *FragFile1 = DEMOS_DATA_DIR "glslstateschange1.frag"; ++static const char *VertFile2 = DEMOS_DATA_DIR "glslstateschange2.vert"; ++static const char *FragFile2 = DEMOS_DATA_DIR "glslstateschange2.frag"; + static struct uniform_info Uniforms1[] = { + { "tex1", 1, GL_SAMPLER_2D, { 0, 0, 0, 0 }, -1 }, + { "tex2", 1, GL_SAMPLER_2D, { 1, 0, 0, 0 }, -1 }, +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-graphics/mesa-demos/mesa-demos_8.1.0.bbappend b/meta-steppeeagle/recipes-graphics/mesa-demos/mesa-demos_8.1.0.bbappend new file mode 100644 index 00000000..b7e42908 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/mesa-demos/mesa-demos_8.1.0.bbappend @@ -0,0 +1,19 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" +EXTRA_OECONF += "--with-system-data-files" +PACKAGECONFIG[glut] = "--with-glut=${STAGING_EXECPREFIXDIR},--without-glut," +DEPENDS_steppeeagle += "mesa-glut glew" +PACKAGECONFIG_append_steppeeagle = " glut" + +SRC_URI += " \ + file://0001-mesa-demos-Use-DEMOS_DATA_DIR-to-locate-data-files.patch \ + file://0001-mesa-demos-Add-missing-data-files.patch \ +" + +do_install_append () { + install -m 0644 ${S}/src/perf/*.frag \ + ${S}/src/perf/*.vert \ + ${S}/src/glsl/*.frag \ + ${S}/src/glsl/*.vert \ + ${S}/src/glsl/*.geom \ + ${S}/src/glsl/*.glsl ${D}${datadir}/${BPN} +} diff --git a/meta-steppeeagle/recipes-graphics/mesa/mesa/0001-radeonsi-add-support-for-Mullins-asics.patch b/meta-steppeeagle/recipes-graphics/mesa/mesa/0001-radeonsi-add-support-for-Mullins-asics.patch new file mode 100644 index 00000000..51b1d070 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/mesa/mesa/0001-radeonsi-add-support-for-Mullins-asics.patch @@ -0,0 +1,74 @@ +From 5dfd2c48a8d4b362a6119a2dcbfe66e163e3af35 Mon Sep 17 00:00:00 2001 +From: Samuel Li <samuel.li@amd.com> +Date: Thu, 17 Apr 2014 15:49:52 -0400 +Subject: [PATCH 1/2] radeonsi: add support for Mullins asics. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + src/gallium/drivers/radeon/r600_pipe_common.c | 2 ++ + src/gallium/drivers/radeonsi/si_state.c | 2 ++ + src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 1 + + src/gallium/winsys/radeon/drm/radeon_winsys.h | 1 + + 4 files changed, 6 insertions(+) + +diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c +index 7508865..db6709a 100644 +--- a/src/gallium/drivers/radeon/r600_pipe_common.c ++++ b/src/gallium/drivers/radeon/r600_pipe_common.c +@@ -293,6 +293,7 @@ static const char* r600_get_name(struct pipe_screen* pscreen) + case CHIP_KAVERI: return "AMD KAVERI"; + case CHIP_KABINI: return "AMD KABINI"; + case CHIP_HAWAII: return "AMD HAWAII"; ++ case CHIP_MULLINS: return "AMD MULLINS"; + default: return "AMD unknown"; + } + } +@@ -410,6 +411,7 @@ const char *r600_get_llvm_processor_name(enum radeon_family family) + case CHIP_KABINI: return "kabini"; + case CHIP_KAVERI: return "kaveri"; + case CHIP_HAWAII: return "hawaii"; ++ case CHIP_MULLINS: return "mullins"; + default: return ""; + #endif + } +diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c +index ab9c4cc..85ef5ae 100644 +--- a/src/gallium/drivers/radeonsi/si_state.c ++++ b/src/gallium/drivers/radeonsi/si_state.c +@@ -3086,6 +3086,8 @@ void si_init_config(struct si_context *sctx) + /* XXX todo */ + case CHIP_KABINI: + /* XXX todo */ ++ case CHIP_MULLINS: ++ /* XXX todo */ + default: + si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG, 0x00000000); + si_pm4_set_reg(pm4, R_028354_PA_SC_RASTER_CONFIG_1, 0x00000000); +diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +index 0eb0c6a..602c406 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c ++++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c +@@ -276,6 +276,7 @@ static boolean do_winsys_init(struct radeon_drm_winsys *ws) + case CHIP_KAVERI: + case CHIP_KABINI: + case CHIP_HAWAII: ++ case CHIP_MULLINS: + ws->info.chip_class = CIK; + break; + } +diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h +index fe0617b..1c0c825 100644 +--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h ++++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h +@@ -130,6 +130,7 @@ enum radeon_family { + CHIP_KAVERI, + CHIP_KABINI, + CHIP_HAWAII, ++ CHIP_MULLINS, + CHIP_LAST, + }; + +-- +1.8.3.1 + diff --git a/meta-steppeeagle/recipes-graphics/mesa/mesa/0002-radeonsi-add-Mullins-pci-ids.patch b/meta-steppeeagle/recipes-graphics/mesa/mesa/0002-radeonsi-add-Mullins-pci-ids.patch new file mode 100644 index 00000000..264fd958 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/mesa/mesa/0002-radeonsi-add-Mullins-pci-ids.patch @@ -0,0 +1,42 @@ +From 5b54f9dac924f9b469105bc664f6bf2b3234f691 Mon Sep 17 00:00:00 2001 +From: Samuel Li <samuel.li@amd.com> +Date: Tue, 12 Nov 2013 15:49:55 -0500 +Subject: [PATCH 2/2] radeonsi: add Mullins pci ids. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + include/pci_ids/radeonsi_pci_ids.h | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/include/pci_ids/radeonsi_pci_ids.h b/include/pci_ids/radeonsi_pci_ids.h +index 7b42d5e..5099c74 100644 +--- a/include/pci_ids/radeonsi_pci_ids.h ++++ b/include/pci_ids/radeonsi_pci_ids.h +@@ -97,6 +97,23 @@ CHIPSET(0x983D, KABINI_983D, KABINI) + CHIPSET(0x983E, KABINI_983E, KABINI) + CHIPSET(0x983F, KABINI_983F, KABINI) + ++CHIPSET(0x9850, MULLINS_9850, MULLINS) ++CHIPSET(0x9851, MULLINS_9851, MULLINS) ++CHIPSET(0x9852, MULLINS_9852, MULLINS) ++CHIPSET(0x9853, MULLINS_9853, MULLINS) ++CHIPSET(0x9854, MULLINS_9854, MULLINS) ++CHIPSET(0x9855, MULLINS_9855, MULLINS) ++CHIPSET(0x9856, MULLINS_9856, MULLINS) ++CHIPSET(0x9857, MULLINS_9857, MULLINS) ++CHIPSET(0x9858, MULLINS_9858, MULLINS) ++CHIPSET(0x9859, MULLINS_9859, MULLINS) ++CHIPSET(0x985A, MULLINS_985A, MULLINS) ++CHIPSET(0x985B, MULLINS_985B, MULLINS) ++CHIPSET(0x985C, MULLINS_985C, MULLINS) ++CHIPSET(0x985D, MULLINS_985D, MULLINS) ++CHIPSET(0x985E, MULLINS_985E, MULLINS) ++CHIPSET(0x985F, MULLINS_985F, MULLINS) ++ + CHIPSET(0x1304, KAVERI_1304, KAVERI) + CHIPSET(0x1305, KAVERI_1305, KAVERI) + CHIPSET(0x1306, KAVERI_1306, KAVERI) +-- +1.8.3.1 + diff --git a/meta-steppeeagle/recipes-graphics/mesa/mesa_git.bbappend b/meta-steppeeagle/recipes-graphics/mesa/mesa_git.bbappend new file mode 100644 index 00000000..7f85de14 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/mesa/mesa_git.bbappend @@ -0,0 +1,60 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +SRCREV = "d4e5ea65089af05b5891293d8947b0ee0e9dd429" +LIC_FILES_CHKSUM = "file://docs/license.html;md5=6a23445982a7a972ac198e93cc1cb3de" +PV = "10.2.0+git${SRCPV}" +DEPENDS += "libvdpau" +PACKAGECONFIG_append = " xvmc openvg gallium gallium-egl gallium-gbm r600" +PACKAGECONFIG_append += " gallium-llvm" +MESA_LLVM_RELEASE = "3.4" + +# Install the demos onto the target +RRECOMMENDS_libgl-mesa += "mesa-demos" + +SRC_URI = " \ + git://people.freedesktop.org/~deathsimple/mesa;branch=vce-release \ + file://0001-radeonsi-add-support-for-Mullins-asics.patch \ + file://0002-radeonsi-add-Mullins-pci-ids.patch \ + " + +PATCHTOOL = "git" + +DEPENDS += "libomxil" +EXTRA_OECONF += "--disable-dri3 \ + --enable-vdpau \ + --enable-osmesa \ + --enable-xa \ + --enable-glx \ + --enable-omx \ + --with-omx-libdir=${libdir}/bellagio \ + " + +PACKAGES += "libxvmcr600-${PN}-dev" +FILES_libxvmcr600-${PN}-dev += "${libdir}/libXvMCr600.so \ + ${libdir}/libXvMCr600.la" + +PACKAGES += "libxvmcnouveau-${PN}-dev" +FILES_libxvmcnouveau-${PN}-dev += "${libdir}/libXvMCnouveau.so \ + ${libdir}/libXvMCnouveau.la" + +PACKAGES += "libvdpau-${PN} libvdpau-${PN}-dev" +FILES_libvdpau-${PN} += "${libdir}/vdpau/libvdpau*.so.*" +FILES_libvdpau-${PN}-dev += "${libdir}/vdpau/libvdpau*.so \ + ${libdir}/vdpau/libvdpau*.la" +FILES_${PN}-dbg += "${libdir}/vdpau/.debug" + +PACKAGES += "libxatracker-${PN} libxatracker-${PN}-dev" +FILES_libxatracker-${PN} += "${libdir}/libxatracker.so.*" +FILES_libxatracker-${PN}-dev += "${includedir}/xa_tracker.h \ + ${includedir}/xa_composite.h \ + ${includedir}/xa_context.h \ + ${libdir}/pkgconfig/xatracker.pc \ + ${libdir}/libxatracker.so \ + ${libdir}/libxatracker.la \ + " + +PACKAGES += "libomx-${PN} libomx-${PN}-dev libomx-${PN}-dbg" +FILES_libomx-${PN} += "${libdir}/bellagio/libomx_*.so.*" +FILES_libomx-${PN}-dev += "${libdir}/bellagio/libomx_*.so \ + ${libdir}/bellagio/libomx_*.la" +FILES_libomx-${PN}-dbg += "${libdir}/bellagio/.debug" diff --git a/meta-steppeeagle/recipes-graphics/vdpauinfo/vdpauinfo_0.1.bb b/meta-steppeeagle/recipes-graphics/vdpauinfo/vdpauinfo_0.1.bb new file mode 100644 index 00000000..aa726b2b --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/vdpauinfo/vdpauinfo_0.1.bb @@ -0,0 +1,15 @@ +DESCRIPTION = "VDPAU info tool" +HOMEPAGE = "http://people.freedesktop.org" +LICENSE = "MIT" + +LIC_FILES_CHKSUM = "file://COPYING;md5=5b6e110c362fe46168199f3490e52c3c" + +SRC_URI = "http://cgit.freedesktop.org/~aplattner/vdpauinfo/snapshot/vdpauinfo-${PV}.zip" +SRC_URI[md5sum] = "62902c9d5d4417885aa70d05521b8280" +SRC_URI[sha256sum] = "b87dd48b2b3b4fc7e886c6963d8dfe8d4dffa3f7b91768a1376ba3e295c28db7" + +inherit autotools pkgconfig + +DEPENDS += "virtual/libx11 libvdpau" + +RDEPENDS_${PN} += "libvdpau-mesa" diff --git a/meta-steppeeagle/recipes-graphics/xorg-driver/glamor-egl_0.6.0.bb b/meta-steppeeagle/recipes-graphics/xorg-driver/glamor-egl_0.6.0.bb new file mode 100644 index 00000000..2628adbe --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/xorg-driver/glamor-egl_0.6.0.bb @@ -0,0 +1,18 @@ +require recipes-graphics/xorg-driver/xorg-driver-common.inc + +LIC_FILES_CHKSUM = "file://COPYING;md5=c7f5e33031114ad132cb03949d73a8a8" + +SRC_URI[md5sum] = "b3668594675f71a75153ee52dbd35535" +SRC_URI[sha256sum] = "66531b56e6054eb53daa7bd57eb6358a7ead1b84f63419606e69d1092365e5c9" + +S = "${WORKDIR}/${PN}-${PV}" + +inherit autotools pkgconfig + +EXTRA_OECONF += "--prefix=${prefix} \ + --sysconfdir=${sysconfdir} \ + --localstatedir=${localstatedir} \ + --enable-glx-tls" + +FILES_${PN} += "${datadir}/X11/xorg.conf.d ${libdir}/xorg/modules/lib*.so" +FILES_${PN}-dbg += "${libdir}/xorg/modules/.debug" diff --git a/meta-steppeeagle/recipes-graphics/xorg-driver/xf86-video-ati/0001-radeon-add-support-for-Mullins.patch b/meta-steppeeagle/recipes-graphics/xorg-driver/xf86-video-ati/0001-radeon-add-support-for-Mullins.patch new file mode 100644 index 00000000..29c1c714 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/xorg-driver/xf86-video-ati/0001-radeon-add-support-for-Mullins.patch @@ -0,0 +1,41 @@ +From 5cf5f62f912c3cd178561ad164f1f51f980e96a9 Mon Sep 17 00:00:00 2001 +From: Samuel Li <samuel.li@amd.com> +Date: Thu, 17 Apr 2014 15:17:28 -0400 +Subject: [PATCH 1/2] radeon: add support for Mullins. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + man/radeon.man | 3 +++ + src/radeon_probe.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/man/radeon.man b/man/radeon.man +index f6a825d..65b880c 100644 +--- a/man/radeon.man ++++ b/man/radeon.man +@@ -208,6 +208,9 @@ KABINI APUs + .TP 12 + .B HAWAII + Radeon R9 series ++.TP 12 ++.B MULLINS ++MULLINS APUs + .PD + .SH CONFIGURATION DETAILS + Please refer to __xconfigfile__(__filemansuffix__) for general configuration +diff --git a/src/radeon_probe.h b/src/radeon_probe.h +index 9500189..3fe4644 100644 +--- a/src/radeon_probe.h ++++ b/src/radeon_probe.h +@@ -116,6 +116,7 @@ typedef enum { + CHIP_FAMILY_KAVERI, + CHIP_FAMILY_KABINI, + CHIP_FAMILY_HAWAII, ++ CHIP_FAMILY_MULLINS, + CHIP_FAMILY_LAST + } RADEONChipFamily; + +-- +1.8.3.1 + diff --git a/meta-steppeeagle/recipes-graphics/xorg-driver/xf86-video-ati/0002-radeon-kms-add-Mullins-pci-ids.patch b/meta-steppeeagle/recipes-graphics/xorg-driver/xf86-video-ati/0002-radeon-kms-add-Mullins-pci-ids.patch new file mode 100644 index 00000000..d3cd5502 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/xorg-driver/xf86-video-ati/0002-radeon-kms-add-Mullins-pci-ids.patch @@ -0,0 +1,181 @@ +From e1484dfd7336aa71ad020968615b1acc0d34fb89 Mon Sep 17 00:00:00 2001 +From: Samuel Li <samuel.li@amd.com> +Date: Tue, 12 Nov 2013 15:30:42 -0500 +Subject: [PATCH 2/2] radeon/kms: add Mullins pci ids. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + src/ati_pciids_gen.h | 16 ++++++++++++++++ + src/pcidb/ati_pciids.csv | 16 ++++++++++++++++ + src/radeon_chipinfo_gen.h | 16 ++++++++++++++++ + src/radeon_chipset_gen.h | 16 ++++++++++++++++ + src/radeon_pci_chipset_gen.h | 16 ++++++++++++++++ + src/radeon_pci_device_match_gen.h | 16 ++++++++++++++++ + 6 files changed, 96 insertions(+) + +diff --git a/src/ati_pciids_gen.h b/src/ati_pciids_gen.h +index eb57992..94c8fc8 100644 +--- a/src/ati_pciids_gen.h ++++ b/src/ati_pciids_gen.h +@@ -722,6 +722,22 @@ + #define PCI_CHIP_KABINI_983D 0x983D + #define PCI_CHIP_KABINI_983E 0x983E + #define PCI_CHIP_KABINI_983F 0x983F ++#define PCI_CHIP_MULLINS_9850 0x9850 ++#define PCI_CHIP_MULLINS_9851 0x9851 ++#define PCI_CHIP_MULLINS_9852 0x9852 ++#define PCI_CHIP_MULLINS_9853 0x9853 ++#define PCI_CHIP_MULLINS_9854 0x9854 ++#define PCI_CHIP_MULLINS_9855 0x9855 ++#define PCI_CHIP_MULLINS_9856 0x9856 ++#define PCI_CHIP_MULLINS_9857 0x9857 ++#define PCI_CHIP_MULLINS_9858 0x9858 ++#define PCI_CHIP_MULLINS_9859 0x9859 ++#define PCI_CHIP_MULLINS_985A 0x985A ++#define PCI_CHIP_MULLINS_985B 0x985B ++#define PCI_CHIP_MULLINS_985C 0x985C ++#define PCI_CHIP_MULLINS_985D 0x985D ++#define PCI_CHIP_MULLINS_985E 0x985E ++#define PCI_CHIP_MULLINS_985F 0x985F + #define PCI_CHIP_KAVERI_1304 0x1304 + #define PCI_CHIP_KAVERI_1305 0x1305 + #define PCI_CHIP_KAVERI_1306 0x1306 +diff --git a/src/pcidb/ati_pciids.csv b/src/pcidb/ati_pciids.csv +index 8469a2a..e334230 100644 +--- a/src/pcidb/ati_pciids.csv ++++ b/src/pcidb/ati_pciids.csv +@@ -723,6 +723,22 @@ + "0x983D","KABINI_983D","KABINI",,1,,,1,"KABINI" + "0x983E","KABINI_983E","KABINI",,1,,,1,"KABINI" + "0x983F","KABINI_983F","KABINI",,1,,,1,"KABINI" ++"0x9850","MULLINS_9850","MULLINS",1,1,,,1,"MULLINS" ++"0x9851","MULLINS_9851","MULLINS",1,1,,,1,"MULLINS" ++"0x9852","MULLINS_9852","MULLINS",1,1,,,1,"MULLINS" ++"0x9853","MULLINS_9853","MULLINS",1,1,,,1,"MULLINS" ++"0x9854","MULLINS_9854","MULLINS",1,1,,,1,"MULLINS" ++"0x9845","MULLINS_9855","MULLINS",1,1,,,1,"MULLINS" ++"0x9856","MULLINS_9856","MULLINS",1,1,,,1,"MULLINS" ++"0x9857","MULLINS_9857","MULLINS",1,1,,,1,"MULLINS" ++"0x9858","MULLINS_9858","MULLINS",1,1,,,1,"MULLINS" ++"0x9859","MULLINS_9859","MULLINS",1,1,,,1,"MULLINS" ++"0x985A","MULLINS_985A","MULLINS",1,1,,,1,"MULLINS" ++"0x985B","MULLINS_985B","MULLINS",1,1,,,1,"MULLINS" ++"0x985C","MULLINS_985C","MULLINS",1,1,,,1,"MULLINS" ++"0x985D","MULLINS_985D","MULLINS",1,1,,,1,"MULLINS" ++"0x985E","MULLINS_985E","MULLINS",1,1,,,1,"MULLINS" ++"0x985F","MULLINS_985F","MULLINS",1,1,,,1,"MULLINS" + "0x1304","KAVERI_1304","KAVERI",1,1,,,1,"KAVERI" + "0x1305","KAVERI_1305","KAVERI",,1,,,1,"KAVERI" + "0x1306","KAVERI_1306","KAVERI",1,1,,,1,"KAVERI" +diff --git a/src/radeon_chipinfo_gen.h b/src/radeon_chipinfo_gen.h +index fc9474b..4f6e3bc 100644 +--- a/src/radeon_chipinfo_gen.h ++++ b/src/radeon_chipinfo_gen.h +@@ -642,6 +642,22 @@ static RADEONCardInfo RADEONCards[] = { + { 0x983D, CHIP_FAMILY_KABINI, 0, 1, 0, 0, 1 }, + { 0x983E, CHIP_FAMILY_KABINI, 0, 1, 0, 0, 1 }, + { 0x983F, CHIP_FAMILY_KABINI, 0, 1, 0, 0, 1 }, ++ { 0x9850, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x9851, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x9852, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x9853, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x9854, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x9855, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x9856, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x9857, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x9858, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x9859, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x985A, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x985B, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x985C, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x985D, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x985E, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, ++ { 0x985F, CHIP_FAMILY_MULLINS, 1, 1, 0, 0, 1 }, + { 0x1304, CHIP_FAMILY_KAVERI, 1, 1, 0, 0, 1 }, + { 0x1305, CHIP_FAMILY_KAVERI, 0, 1, 0, 0, 1 }, + { 0x1306, CHIP_FAMILY_KAVERI, 1, 1, 0, 0, 1 }, +diff --git a/src/radeon_chipset_gen.h b/src/radeon_chipset_gen.h +index afab6b0..03a413e 100644 +--- a/src/radeon_chipset_gen.h ++++ b/src/radeon_chipset_gen.h +@@ -642,6 +642,22 @@ SymTabRec RADEONChipsets[] = { + { PCI_CHIP_KABINI_983D, "KABINI" }, + { PCI_CHIP_KABINI_983E, "KABINI" }, + { PCI_CHIP_KABINI_983F, "KABINI" }, ++ { PCI_CHIP_MULLINS_9850, "MULLINS" }, ++ { PCI_CHIP_MULLINS_9851, "MULLINS" }, ++ { PCI_CHIP_MULLINS_9852, "MULLINS" }, ++ { PCI_CHIP_MULLINS_9853, "MULLINS" }, ++ { PCI_CHIP_MULLINS_9854, "MULLINS" }, ++ { PCI_CHIP_MULLINS_9855, "MULLINS" }, ++ { PCI_CHIP_MULLINS_9856, "MULLINS" }, ++ { PCI_CHIP_MULLINS_9857, "MULLINS" }, ++ { PCI_CHIP_MULLINS_9858, "MULLINS" }, ++ { PCI_CHIP_MULLINS_9859, "MULLINS" }, ++ { PCI_CHIP_MULLINS_985A, "MULLINS" }, ++ { PCI_CHIP_MULLINS_985B, "MULLINS" }, ++ { PCI_CHIP_MULLINS_985C, "MULLINS" }, ++ { PCI_CHIP_MULLINS_985D, "MULLINS" }, ++ { PCI_CHIP_MULLINS_985E, "MULLINS" }, ++ { PCI_CHIP_MULLINS_985F, "MULLINS" }, + { PCI_CHIP_KAVERI_1304, "KAVERI" }, + { PCI_CHIP_KAVERI_1305, "KAVERI" }, + { PCI_CHIP_KAVERI_1306, "KAVERI" }, +diff --git a/src/radeon_pci_chipset_gen.h b/src/radeon_pci_chipset_gen.h +index da4440b..a9b186c 100644 +--- a/src/radeon_pci_chipset_gen.h ++++ b/src/radeon_pci_chipset_gen.h +@@ -642,6 +642,22 @@ static PciChipsets RADEONPciChipsets[] = { + { PCI_CHIP_KABINI_983D, PCI_CHIP_KABINI_983D, RES_SHARED_VGA }, + { PCI_CHIP_KABINI_983E, PCI_CHIP_KABINI_983E, RES_SHARED_VGA }, + { PCI_CHIP_KABINI_983F, PCI_CHIP_KABINI_983F, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9850, PCI_CHIP_MULLINS_9850, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9851, PCI_CHIP_MULLINS_9851, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9852, PCI_CHIP_MULLINS_9852, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9853, PCI_CHIP_MULLINS_9853, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9854, PCI_CHIP_MULLINS_9854, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9855, PCI_CHIP_MULLINS_9855, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9856, PCI_CHIP_MULLINS_9856, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9857, PCI_CHIP_MULLINS_9857, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9858, PCI_CHIP_MULLINS_9858, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_9859, PCI_CHIP_MULLINS_9859, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_985A, PCI_CHIP_MULLINS_985A, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_985B, PCI_CHIP_MULLINS_985B, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_985C, PCI_CHIP_MULLINS_985C, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_985D, PCI_CHIP_MULLINS_985D, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_985E, PCI_CHIP_MULLINS_985E, RES_SHARED_VGA }, ++ { PCI_CHIP_MULLINS_985F, PCI_CHIP_MULLINS_985F, RES_SHARED_VGA }, + { PCI_CHIP_KAVERI_1304, PCI_CHIP_KAVERI_1304, RES_SHARED_VGA }, + { PCI_CHIP_KAVERI_1305, PCI_CHIP_KAVERI_1305, RES_SHARED_VGA }, + { PCI_CHIP_KAVERI_1306, PCI_CHIP_KAVERI_1306, RES_SHARED_VGA }, +diff --git a/src/radeon_pci_device_match_gen.h b/src/radeon_pci_device_match_gen.h +index d4b3763..a73d9c1 100644 +--- a/src/radeon_pci_device_match_gen.h ++++ b/src/radeon_pci_device_match_gen.h +@@ -642,6 +642,22 @@ static const struct pci_id_match radeon_device_match[] = { + ATI_DEVICE_MATCH( PCI_CHIP_KABINI_983D, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_KABINI_983E, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_KABINI_983F, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9850, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9851, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9852, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9853, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9854, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9855, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9856, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9857, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9858, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_9859, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_985A, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_985B, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_985C, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_985D, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_985E, 0 ), ++ ATI_DEVICE_MATCH( PCI_CHIP_MULLINS_985F, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_KAVERI_1304, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_KAVERI_1305, 0 ), + ATI_DEVICE_MATCH( PCI_CHIP_KAVERI_1306, 0 ), +-- +1.8.3.1 + diff --git a/meta-steppeeagle/recipes-graphics/xorg-driver/xf86-video-ati_git.bb b/meta-steppeeagle/recipes-graphics/xorg-driver/xf86-video-ati_git.bb new file mode 100644 index 00000000..70676d0b --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/xorg-driver/xf86-video-ati_git.bb @@ -0,0 +1,38 @@ +require recipes-graphics/xorg-driver/xorg-driver-video.inc + +SUMMARY = "X.Org X server -- ATI integrated graphics chipsets driver" + +DESCRIPTION = "xf86-video-ati is an Xorg driver for Intel integrated \ +graphics chipsets. The driver supports depths 8, 15, 16 and 24. On \ +some chipsets, the driver supports hardware accelerated 3D via the \ +Direct Rendering Infrastructure (DRI)." + +LIC_FILES_CHKSUM = "file://COPYING;md5=aabff1606551f9461ccf567739af63dc" + +DEPENDS += "virtual/libx11 drm dri2proto glproto \ + virtual/libgl xineramaproto libpciaccess \ + udev glamor-egl" + +SRCREV = "48d3dbc8a0d3bfde88f46e402e530438f9317715" +PV = "7.3.99+git${SRCPV}" +PR = "${INC_PR}.1" + +EXTRA_OECONF += "--enable-udev --enable-glamor" + +SRC_URI = " \ + git://anongit.freedesktop.org/git/xorg/driver/xf86-video-ati \ + file://0001-radeon-add-support-for-Mullins.patch \ + file://0002-radeon-kms-add-Mullins-pci-ids.patch \ + " + +PATCHTOOL = "git" + +S = "${WORKDIR}/git" + +RDEPENDS_${PN} += "libgbm-gallium \ + mesa-driver-radeon \ + mesa-driver-radeonsi \ + mesa-driver-swrast \ + " + +COMPATIBLE_HOST = '(i.86|x86_64).*-linux' diff --git a/meta-steppeeagle/recipes-graphics/xorg-lib/libvdpau_0.7.bb b/meta-steppeeagle/recipes-graphics/xorg-lib/libvdpau_0.7.bb new file mode 100644 index 00000000..f6b9afe2 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/xorg-lib/libvdpau_0.7.bb @@ -0,0 +1,39 @@ +DESCRIPTION = "Implements VDPAU library" +HOMEPAGE = "http://people.freedesktop.org" +LICENSE = "MIT" +DEPENDS = "xtrans libx11 libxext libice libsm libxscrnsaver libxt \ + libxmu libxpm libxau libxfixes libxcomposite libxrender \ + libxcursor libxdamage libfontenc libxfont libxft libxi \ + libxinerama libxrandr libxres libxtst libxv libxvmc \ + libxxf86dga libxxf86vm libdmx libpciaccess libxkbfile \ + dri2proto \ + " +LIC_FILES_CHKSUM = "file://COPYING;md5=83af8811a28727a13f04132cc33b7f58" + +SRC_URI = "http://people.freedesktop.org/~aplattner/vdpau/libvdpau-${PV}.tar.gz" +SRC_URI[md5sum] = "cb81b0c3b7d32b2b2a51894ef05b95ce" +SRC_URI[sha256sum] = "24dc08467ce8c59d6cfbf0d34d2dd1f86b4ff62e90777e0a8f513c5c9de9bce0" + +inherit autotools pkgconfig + +S = "${WORKDIR}/libvdpau-${PV}" + +FILES_${PN} += "${libdir}/vdpau/libvdpau_nouveau.so.* \ + ${libdir}/vdpau/libvdpau_r600.so.* \ + ${libdir}/vdpau/libvdpau_radeonsi.so.* \ + ${libdir}/vdpau/libvdpau_trace.so.* \ + " + +FILES_${PN}-dev += "${libdir}/vdpau/libvdpau_nouveau.so \ + ${libdir}/vdpau/libvdpau_nouveau.la \ + ${libdir}/vdpau/libvdpau_r600.so \ + ${libdir}/vdpau/libvdpau_r600.la \ + ${libdir}/vdpau/libvdpau_radeonsi.so \ + ${libdir}/vdpau/libvdpau_radeonsi.la \ + ${libdir}/vdpau/libvdpau_trace.so \ + ${libdir}/vdpau/libvdpau_trace.la \ + " + +FILES_${PN}-dbg += "${libdir}/vdpau/.debug" + +EXTRA_OECONF += "--enable-dri2" diff --git a/meta-steppeeagle/recipes-graphics/xorg-xserver/xserver-xf86-config/steppeeagle/xorg.conf b/meta-steppeeagle/recipes-graphics/xorg-xserver/xserver-xf86-config/steppeeagle/xorg.conf new file mode 100644 index 00000000..17363bc6 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/xorg-xserver/xserver-xf86-config/steppeeagle/xorg.conf @@ -0,0 +1,113 @@ +# TODO: imported from /usr/local/xorg/share/X11/conf.d/glamor.conf +Section "Module" + Load "dri2" + Load "glamoregl" +EndSection + +Section "Monitor" + Identifier "Monitor0" + VendorName "Monitor Vendor" + ModelName "Monitor Model" +EndSection + +Section "Device" + ### Available Driver options are:- + ### Values: <i>: integer, <f>: float, <bool>: "True"/"False", + ### <string>: "String", <freq>: "<f> Hz/kHz/MHz", + ### <percent>: "<f>%" + ### [arg]: arg optional + #Option "NoAccel" # [<bool>] + #Option "SWcursor" # [<bool>] + #Option "Dac6Bit" # [<bool>] + #Option "Dac8Bit" # [<bool>] + #Option "BusType" # [<str>] + #Option "CPPIOMode" # [<bool>] + #Option "CPusecTimeout" # <i> + #Option "AGPMode" # <i> + #Option "AGPFastWrite" # [<bool>] + #Option "AGPSize" # <i> + #Option "GARTSize" # <i> + #Option "RingSize" # <i> + #Option "BufferSize" # <i> + #Option "EnableDepthMoves" # [<bool>] + #Option "EnablePageFlip" # [<bool>] + #Option "NoBackBuffer" # [<bool>] + #Option "DMAForXv" # [<bool>] + #Option "FBTexPercent" # <i> + #Option "DepthBits" # <i> + #Option "PCIAPERSize" # <i> + #Option "AccelDFS" # [<bool>] + #Option "IgnoreEDID" # [<bool>] + #Option "CustomEDID" # [<str>] + #Option "DisplayPriority" # [<str>] + #Option "PanelSize" # [<str>] + #Option "ForceMinDotClock" # <freq> + #Option "ColorTiling" # [<bool>] + #Option "VideoKey" # <i> + #Option "RageTheatreCrystal" # <i> + #Option "RageTheatreTunerPort" # <i> + #Option "RageTheatreCompositePort" # <i> + #Option "RageTheatreSVideoPort" # <i> + #Option "TunerType" # <i> + #Option "RageTheatreMicrocPath" # <str> + #Option "RageTheatreMicrocType" # <str> + #Option "ScalerWidth" # <i> + #Option "RenderAccel" # [<bool>] + #Option "SubPixelOrder" # [<str>] + #Option "ClockGating" # [<bool>] + #Option "VGAAccess" # [<bool>] + #Option "ReverseDDC" # [<bool>] + #Option "LVDSProbePLL" # [<bool>] + Option "AccelMethod" "glamor" + #Option "DRI" # [<bool>] + #Option "ConnectorTable" # <str> + #Option "DefaultConnectorTable" # [<bool>] + #Option "DefaultTMDSPLL" # [<bool>] + #Option "TVDACLoadDetect" # [<bool>] + #Option "ForceTVOut" # [<bool>] + #Option "TVStandard" # <str> + #Option "IgnoreLidStatus" # [<bool>] + #Option "DefaultTVDACAdj" # [<bool>] + #Option "Int10" # [<bool>] + #Option "EXAVSync" # [<bool>] + #Option "ATOMTVOut" # [<bool>] + #Option "R4xxATOM" # [<bool>] + #Option "ForceLowPowerMode" # [<bool>] + #Option "DynamicPM" # [<bool>] + #Option "NewPLL" # [<bool>] + #Option "ZaphodHeads" # <str> + Identifier "Card0" + Driver "radeon" + BusID "PCI:0:1:0" +EndSection + +Section "Screen" + Identifier "Screen0" + Device "Card0" + Monitor "Monitor0" + SubSection "Display" + Viewport 0 0 + Depth 1 + EndSubSection + SubSection "Display" + Viewport 0 0 + Depth 4 + EndSubSection + SubSection "Display" + Viewport 0 0 + Depth 8 + EndSubSection + SubSection "Display" + Viewport 0 0 + Depth 15 + EndSubSection + SubSection "Display" + Viewport 0 0 + Depth 16 + EndSubSection + SubSection "Display" + Viewport 0 0 + Depth 24 + EndSubSection +EndSection + diff --git a/meta-steppeeagle/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend b/meta-steppeeagle/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend new file mode 100644 index 00000000..72d991c7 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend @@ -0,0 +1 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" diff --git a/meta-steppeeagle/recipes-graphics/xorg-xserver/xserver-xorg_1.15.0.bbappend b/meta-steppeeagle/recipes-graphics/xorg-xserver/xserver-xorg_1.15.0.bbappend new file mode 100644 index 00000000..aa1ecd66 --- /dev/null +++ b/meta-steppeeagle/recipes-graphics/xorg-xserver/xserver-xorg_1.15.0.bbappend @@ -0,0 +1,5 @@ +PR = "${INC_PR}.1" +EXTRA_OECONF += "--enable-aiglx \ + --enable-xvmc \ + --enable-libdrm \ + " diff --git a/meta-steppeeagle/recipes-kernel/amd-gpio/amd-gpio_1.0.bb b/meta-steppeeagle/recipes-kernel/amd-gpio/amd-gpio_1.0.bb new file mode 100644 index 00000000..c003fe43 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-gpio/amd-gpio_1.0.bb @@ -0,0 +1,28 @@ +DESCRIPTION = "This kernel module provides support for AMD GPIO driver" +LICENSE = "BSD | GPLv2" +LIC_FILES_CHKSUM = "file://gpio-amd.c;md5=a48cb57d6711b1801a62ea03a87e2e76 \ + file://gpio-amd.h;md5=90e0a4a5923224a946619ee72f0f7522 \ + file://Makefile;md5=1bede035509502b1669f098efbd904f3 \ + " + +inherit module + +PR = "r0" +PV = "1.0" + +SRC_URI = "file://Makefile \ + file://gpio-amd.c \ + file://gpio-amd.h \ + " + +S = "${WORKDIR}" + +# Kernel module packages MUST begin with 'kernel-module-', otherwise +# multilib image generation can fail. +# +# The following line is only necessary if the recipe name does not begin +# with kernel-module-. +# +PKG_${PN} = "kernel-module-${PN}" + +FILES_${PN} += "${sysconfdir}" diff --git a/meta-steppeeagle/recipes-kernel/amd-gpio/files/Makefile b/meta-steppeeagle/recipes-kernel/amd-gpio/files/Makefile new file mode 100644 index 00000000..b9348759 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-gpio/files/Makefile @@ -0,0 +1,14 @@ +obj-m := gpio-amd.o + +SRC := $(shell pwd) + +all: + $(MAKE) -C $(KERNEL_SRC) M=$(SRC) + +clean: + rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c + rm -f Module.markers Module.symvers modules.order + rm -rf .tmp_versions Modules.symvers + +modules_install: + $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
\ No newline at end of file diff --git a/meta-steppeeagle/recipes-kernel/amd-gpio/files/gpio-amd.c b/meta-steppeeagle/recipes-kernel/amd-gpio/files/gpio-amd.c new file mode 100644 index 00000000..6c790c11 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-gpio/files/gpio-amd.c @@ -0,0 +1,886 @@ +/***************************************************************************** +* +* Copyright (c) 2014, Advanced Micro Devices, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Advanced Micro Devices, Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +***************************************************************************/ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/gpio.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> +#include <linux/uaccess.h> +#include <linux/io.h> + +#include <asm/io.h> + +#include <linux/cdev.h> +#include <linux/fs.h> /* everything... */ +#include <asm/io.h> +#include <linux/ioctl.h> +#include <linux/device.h> + +#include "gpio-amd.h" + +static u32 gpiobase_phys; +static u32 iomuxbase_phys; +static struct pci_dev *amd_gpio_pci; +static struct platform_device *amd_gpio_platform_device; + + +static int dev_major; +static int dev_minor = 0; + +static struct gpio_test_dev{ + struct cdev cdev; + struct class *gpio_class; +}gpio_test_dev; + + +/* The following GPIO pins are reserved as per the specification. 184 max */ +static u8 mask[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +}; + + +static int gpio_mask[AMD_GPIO_NUM_PINS]; +static unsigned int num_mask; +module_param_array(gpio_mask, int, &num_mask, 0); +MODULE_PARM_DESC(gpio_mask, "GPIO mask which marks them as reserved"); + +static int gpio_mode[AMD_GPIO_NUM_PINS]; +static unsigned int num_modes; +module_param_array(gpio_mode, int, &num_modes, 0); +MODULE_PARM_DESC(gpio_mode, "Specifies whether the GPIO mentioned " + "in gpio_mask is 0-reserved, 1-available, 2-GPI only, " + "3-GPO only"); + +static struct amd_gpio_chip { + struct gpio_chip gpio; + + void __iomem *gpiobase; + void __iomem *iomuxbase; + + struct platform_device *pdev; + spinlock_t lock; +} amd_gpio_chip; + +static int amd_gpio_request(struct gpio_chip *c, unsigned offset) +{ + struct amd_gpio_chip *chip = container_of(c, struct amd_gpio_chip, + gpio); + unsigned long flags; + u8 iomux_reg; + u32 gpio_reg = 0; + + spin_lock_irqsave(&chip->lock, flags); + + /* check if this pin is available */ + if (mask[offset] == AMD_GPIO_MODE_RESV) { + spin_unlock_irqrestore(&chip->lock, flags); + pr_info("GPIO pin %u not available\n", offset); + return -EINVAL; + } + + /* Program the GPIO Wake/Interrupt Switch offset is AMD_GPIO_MSWITCH */ + gpio_reg = ioread32((u32 *)amd_gpio_chip.gpiobase + AMD_GPIO_MSWITCH); + /* to disable all GPIO wake and interrupt*/ + gpio_reg &= (~AMD_GPIO_WAKE_EN & ~AMD_GPIO_INTERRUPT_EN); + iowrite32(gpio_reg, ((u32 *)amd_gpio_chip.gpiobase + AMD_GPIO_MSWITCH)); + + gpio_reg = ioread32((u32 *)amd_gpio_chip.gpiobase + offset); + /* clear wake status and interrupt status */ + gpio_reg |= (AMD_GPIO_INTERPT_STATUS | AMD_GPIO_WAKE_STATUS); + + /* Set disable both Pull Up and Pull Down and disable output */ + gpio_reg &= (~AMD_GPIO_PULLUP_ENABLE & ~AMD_GPIO_PULLDN_ENABLE + & ~AMD_GPIO_DEB_CTRL & ~AMD_GPIO_SWCTRL_IN + & ~AMD_GPIO_WAKECTRL & ~AMD_GPIO_INTERPT_ENABLE); + iowrite32(gpio_reg, ((u32 *)amd_gpio_chip.gpiobase + offset)); + + /* Enable GPIO by writing to the corresponding IOMUX register */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + offset); + iomux_reg &= ~AMD_IOMUX_GPIO_MASK; + + if(offset == 10 || offset == 72 || offset == 73 ||offset == 76) + iomux_reg |= AMD_IOMUX_ENABLE_FUNC0; + else if(offset == 35 || offset == 64 || offset == 65 ||offset == 66 || + offset == 71 || offset == 93 ||offset == 115 ||offset == 116) + iomux_reg |= AMD_IOMUX_ENABLE_FUNC2; + else if(offset == 67 || offset == 70) + iomux_reg |= AMD_IOMUX_ENABLE_FUNC3; + else + iomux_reg |= AMD_IOMUX_ENABLE_FUNC1; + + iowrite8(iomux_reg, ((u8 *)amd_gpio_chip.iomuxbase + offset)); + + spin_unlock_irqrestore(&chip->lock, flags); + + return 0; +} + + +static int amd_gpio_get(struct gpio_chip *c, unsigned offset) +{ + struct amd_gpio_chip *chip = container_of(c, struct amd_gpio_chip, + gpio); + unsigned long flags; + u32 gpio_reg; + + spin_lock_irqsave(&chip->lock, flags); + + /* Read the GPIO register */ + gpio_reg = ioread32((u32 *)amd_gpio_chip.gpiobase + offset); + + spin_unlock_irqrestore(&chip->lock, flags); + + return (gpio_reg & AMD_GPIO_GET_INPUT) ? 1 : 0; +} + +static void amd_gpio_set(struct gpio_chip *c, unsigned offset, int val) +{ + struct amd_gpio_chip *chip = container_of(c, struct amd_gpio_chip, + gpio); + unsigned long flags; + u32 gpio_reg; + + spin_lock_irqsave(&chip->lock, flags); + + gpio_reg = ioread32((u32 *)amd_gpio_chip.gpiobase + offset); + + /* Set GPIO Output depending on 'val' */ + if (val) + gpio_reg |= AMD_GPIO_SET_OUTPUT; + else + gpio_reg &= ~AMD_GPIO_SET_OUTPUT; + + iowrite32(gpio_reg, ((u32 *)amd_gpio_chip.gpiobase + offset)); + + spin_unlock_irqrestore(&chip->lock, flags); +} + +static int amd_gpio_direction_input(struct gpio_chip *c, unsigned offset) +{ + struct amd_gpio_chip *chip = container_of(c, struct amd_gpio_chip, + gpio); + unsigned long flags; + u32 gpio_reg; + + spin_lock_irqsave(&chip->lock, flags); + + /* If the mask says the pin should be GPO, we return from here */ + if (mask[offset] == AMD_GPIO_MODE_OUTPUT) { + pr_info("GPIO %u can only be set in output mode\n", offset); + spin_unlock_irqrestore(&chip->lock, flags); + return -EINVAL; + } + + gpio_reg = ioread32((u32 *)amd_gpio_chip.gpiobase + offset); + /* Disable output by set the bit to 0 */ + gpio_reg &= ~AMD_GPIO_OUTPUT_ENABLE; + iowrite32(gpio_reg, ((u32 *)amd_gpio_chip.gpiobase + offset)); + + spin_unlock_irqrestore(&chip->lock, flags); + + return 0; +} + +static int amd_gpio_direction_output(struct gpio_chip *c, unsigned offset, + int val) +{ + struct amd_gpio_chip *chip = container_of(c, struct amd_gpio_chip, + gpio); + unsigned long flags; + u32 gpio_reg; + + spin_lock_irqsave(&chip->lock, flags); + + /* If the mask says the pin should be GPI, we return from here */ + if (mask[offset] == AMD_GPIO_MODE_INPUT) { + pr_info("GPIO %u can only be set in input mode\n", offset); + spin_unlock_irqrestore(&chip->lock, flags); + return -EINVAL; + } + + gpio_reg = ioread32((u32 *)amd_gpio_chip.gpiobase + offset); + + + gpio_reg |= AMD_GPIO_DRV_STRENGTH(2); + /* Set disable both Pull Up and Pull Down */ + gpio_reg &= (~AMD_GPIO_PULLUP_ENABLE & ~AMD_GPIO_PULLDN_ENABLE + & ~AMD_GPIO_DEB_CTRL & ~AMD_GPIO_SWCTRL_IN + & ~AMD_GPIO_WAKECTRL & ~AMD_GPIO_INTERPT_ENABLE); + /* Enable output */ + gpio_reg |= AMD_GPIO_OUTPUT_ENABLE; + + /* Set GPIO Output depending on 'val' */ + if (val) + gpio_reg |= AMD_GPIO_SET_OUTPUT; + else + gpio_reg &= ~AMD_GPIO_SET_OUTPUT; + + iowrite32(gpio_reg, ((u32 *)amd_gpio_chip.gpiobase + offset)); + + spin_unlock_irqrestore(&chip->lock, flags); + + return 0; +} + +static struct amd_gpio_chip amd_gpio_chip = { + .gpio = { + .owner = THIS_MODULE, + .label = DRV_NAME, + + .base = 0, + .ngpio = AMD_GPIO_NUM_PINS, + .names = NULL, + .request = amd_gpio_request, + .get = amd_gpio_get, + .set = amd_gpio_set, + .direction_input = amd_gpio_direction_input, + .direction_output = amd_gpio_direction_output, + }, +}; + +/* +* The PCI Device ID table below is used to identify the platform +* the driver is supposed to work for. Since this is a platform +* driver, we need a way for us to be able to find the correct +* platform when the driver gets loaded, otherwise we should +* bail out. +*/ +static DEFINE_PCI_DEVICE_TABLE(amd_gpio_pci_tbl) = { + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, PCI_ANY_ID, + PCI_ANY_ID, }, + { 0, }, +}; + +MODULE_DEVICE_TABLE(pci, amd_gpio_pci_tbl); + +static void amd_update_gpio_mask(void) +{ + u8 iomux_reg; + + /* + * Some of the GPIO pins have an alternate function assigned to + * them. That will be reflected in the corresponding IOMUX + * registers. If so, we mark these GPIO pins as reserved. + */ + + /* AGPIO10 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x0A); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[10] = AMD_GPIO_MODE_RESV; + + /* EGPIO19 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x13); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[19] = AMD_GPIO_MODE_RESV; + + /* EGPIO20 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x14); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[20] = AMD_GPIO_MODE_RESV; + + /* EGPIO26 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x1A); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[26] = AMD_GPIO_MODE_RESV; + + /* EGPIO27 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x1B); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[27] = AMD_GPIO_MODE_RESV; + + /* EGPIO28 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x1C); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[28] = AMD_GPIO_MODE_RESV; + + /* EGPIO29 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x1D); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[29] = AMD_GPIO_MODE_RESV; + + /* EGPIO30 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x1E); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[30] = AMD_GPIO_MODE_RESV; + + /* EGPIO31 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x1F); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[31] = AMD_GPIO_MODE_RESV; + + /* EGPIO35 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x23); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[35] = AMD_GPIO_MODE_RESV; + + /* AGPIO64 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x40); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[64] = AMD_GPIO_MODE_RESV; + + /* AGPIO65 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x41); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[65] = AMD_GPIO_MODE_RESV; + + /* AGPIO66 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x42); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[66] = AMD_GPIO_MODE_RESV; + + /* AGPIO67 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x43); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2)) + mask[67] = AMD_GPIO_MODE_RESV; + + /* AGPIO68 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x44); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[68] = AMD_GPIO_MODE_RESV; + + /* AGPIO69 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x45); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[68] = AMD_GPIO_MODE_RESV; + + /* AGPIO70 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x46); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2)) + mask[70] = AMD_GPIO_MODE_RESV; + + /* AGPIO71 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x47); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[71] = AMD_GPIO_MODE_RESV; + + /* AGPIO72 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x48); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[72] = AMD_GPIO_MODE_RESV; + + /* AGPIO73 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x49); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[73] = AMD_GPIO_MODE_RESV; + + /* AGPIO76 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x4C); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[76] = AMD_GPIO_MODE_RESV; + + /* AGPIO77 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x4D); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[77] = AMD_GPIO_MODE_RESV; + + /* EGPIO84 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x54); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[84] = AMD_GPIO_MODE_RESV; + + /* EGPIO85 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x55); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[85] = AMD_GPIO_MODE_RESV; + + /* EGPIO87 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x57); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[87] = AMD_GPIO_MODE_RESV; + + /* EGPIO88 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x58); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[88] = AMD_GPIO_MODE_RESV; + + /* AGPIO91 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x5B); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[91] = AMD_GPIO_MODE_RESV; + + /* EGPIO93 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x5D); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[93] = AMD_GPIO_MODE_RESV; + + /* EGPIO115 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x73); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[115] = AMD_GPIO_MODE_RESV; + + /* EGPIO116 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x74); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC1) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[116] = AMD_GPIO_MODE_RESV; + + /* AGPIO130 */ + iomux_reg = ioread8((u8 *)amd_gpio_chip.iomuxbase + 0x82); + if (((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC0) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC2) || + ((iomux_reg & AMD_IOMUX_GPIO_MASK) == AMD_IOMUX_ENABLE_FUNC3)) + mask[86] = AMD_GPIO_MODE_RESV; +} + +static int amd_gpio_init(struct platform_device *pdev) +{ + struct pci_dev *dev = NULL; + int i; + int err; + + /* Match the PCI device */ + for_each_pci_dev(dev) { + if (pci_match_id(amd_gpio_pci_tbl, dev) != NULL) { + amd_gpio_pci = dev; + break; + } + } + + if (!amd_gpio_pci) + return -ENODEV; + + /* GPIO registers range from AMD_GPIO_ACPIMMIO_BASE+1500h to + AMD_GPIO_ACPIMMIO_BASE+17FFh. */ + if (!request_mem_region_exclusive(AMD_GPIO_ACPIMMIO_BASE + + AMD_GPIO_BANK_OFFSET, AMD_GPIO_MEM_MAP_SIZE, "AMD GPIO")) { + pr_err("mmio address 0x%04x already in use\n", + AMD_GPIO_ACPIMMIO_BASE + AMD_GPIO_BANK_OFFSET ); + goto exit; + } + gpiobase_phys = AMD_GPIO_ACPIMMIO_BASE + AMD_GPIO_BANK_OFFSET; + + amd_gpio_chip.gpiobase = ioremap(gpiobase_phys, AMD_GPIO_MEM_MAP_SIZE); + if (!amd_gpio_chip.gpiobase) { + pr_err("failed to get gpiobase address\n"); + goto unreg_gpio_region; + } + + /* IOMUX Base Address starts from ACPI MMIO Base Address + 0xD00 */ + if (!request_mem_region_exclusive(AMD_GPIO_ACPIMMIO_BASE + + AMD_IOMUX_MEM_MAP_OFFSET, + AMD_IOMUX_MEM_MAP_SIZE, "AMD IOMUX")) { + pr_err("mmio address 0x%04x already in use\n", + AMD_GPIO_ACPIMMIO_BASE + AMD_IOMUX_MEM_MAP_OFFSET); + goto unmap_gpio_region; + } + iomuxbase_phys = AMD_GPIO_ACPIMMIO_BASE + AMD_IOMUX_MEM_MAP_OFFSET; + + amd_gpio_chip.iomuxbase = ioremap(iomuxbase_phys, + AMD_IOMUX_MEM_MAP_SIZE); + if (!amd_gpio_chip.iomuxbase) { + pr_err("failed to get iomuxbase address\n"); + goto unreg_iomux_region; + } + + /* Set up driver specific struct */ + amd_gpio_chip.pdev = pdev; + spin_lock_init(&amd_gpio_chip.lock); + + /* Register ourself with the GPIO core */ + err = gpiochip_add(&amd_gpio_chip.gpio); + if (err) + goto unmap_iomux_region; + + /* + * Lets take care of special GPIO pins, and mark them as reserved + * as appropriate. + */ + amd_update_gpio_mask(); + + /* + * If the number of GPIO pins provided during module loading does + * not match the number of GPIO modes, we fall back to the default + * mask. + */ + if (num_mask == num_modes) { + /* + * If the number of masks or the number of modes specified + * is more than the maximum number of GPIO pins supported + * by the driver, we set the limit to the one supported + * driver. + */ + if (num_mask > AMD_GPIO_NUM_PINS) + num_mask = num_modes = AMD_GPIO_NUM_PINS; + + /* + * The default mask is our de facto standard. The GPIO + * pins marked reserved in the default mask stay reserved + * no matter what the module load parameter says. Also, we + * set the mode of the GPIO pins depending on the value + * of gpio_mode provided. + */ + for (i = 0; i < num_mask; i++) { + if (mask[gpio_mask[i]] != AMD_GPIO_MODE_RESV) { + mask[gpio_mask[i]] = gpio_mode[i]; + + /* + * gpio_request() can fail, in which case we + * won't set the GPIO modes. + */ + if(!gpio_request(gpio_mask[i], DRV_NAME)) { + if (gpio_mode[i] == + AMD_GPIO_MODE_INPUT) + gpio_direction_input(gpio_mask[i]); + else if (gpio_mode[i] == + AMD_GPIO_MODE_OUTPUT) + gpio_direction_output(gpio_mask[i], + 0); + + gpio_free(gpio_mask[i]); + } + } + } + } + + return 0; + +unmap_iomux_region: + iounmap(amd_gpio_chip.iomuxbase); +unreg_iomux_region: + release_mem_region(iomuxbase_phys, AMD_IOMUX_MEM_MAP_SIZE); +unmap_gpio_region: + iounmap(amd_gpio_chip.gpiobase); +unreg_gpio_region: + release_mem_region(gpiobase_phys, AMD_GPIO_MEM_MAP_SIZE); +exit: + return -ENODEV; +} + +static int amd_gpio_remove(struct platform_device *pdev) +{ + int err; + + err = gpiochip_remove(&amd_gpio_chip.gpio); + if (err) { + dev_err(&pdev->dev, "Unable to remove gpio chip\n"); + return err; + } + + iounmap(amd_gpio_chip.iomuxbase); + release_mem_region(iomuxbase_phys, AMD_IOMUX_MEM_MAP_SIZE); + iounmap(amd_gpio_chip.gpiobase); + release_mem_region(gpiobase_phys, AMD_GPIO_MEM_MAP_SIZE); + + return 0; +} + +static struct platform_driver amd_gpio_driver = { + .probe = amd_gpio_init, + .remove = amd_gpio_remove, + .driver = { + .owner = THIS_MODULE, + .name = GPIO_MODULE_NAME, + }, +}; + +/* interface to debug driver for gpio */ + +static int amd_gpio_swctrlen(int offset, int value) +{ + struct amd_gpio_chip *chip = &amd_gpio_chip; + u32 gpio_reg; + unsigned long flags; + + spin_lock_irqsave(&chip->lock, flags); + + /* If the mask says the pin should be GPO, we return from here */ + if (mask[offset] == AMD_GPIO_MODE_RESV) { + pr_info("GPIO %u is reserved\n", offset); + spin_unlock_irqrestore(&chip->lock, flags); + return -EINVAL; + } + + if (mask[offset] == AMD_GPIO_MODE_OUTPUT) { + pr_info("GPIO %u can only be set in output mode\n", offset); + spin_unlock_irqrestore(&chip->lock, flags); + return -EINVAL; + } + + gpio_reg = ioread32((u32 *)amd_gpio_chip.gpiobase + offset); + /* Disable output by set the bit to 0 */ + gpio_reg &= ~AMD_GPIO_OUTPUT_ENABLE; + /* enable or disable sw input */ + if(value) + gpio_reg |= AMD_GPIO_SWCTRL_EN; + else + gpio_reg &= ~AMD_GPIO_SWCTRL_EN; + + iowrite32(gpio_reg, ((u32 *)amd_gpio_chip.gpiobase + offset)); + + spin_unlock_irqrestore(&chip->lock, flags); + + return 0; +} + +static int amd_gpio_swctrlin(int offset, int value) +{ + struct amd_gpio_chip *chip = &amd_gpio_chip; + u32 gpio_reg; + unsigned long flags; + + spin_lock_irqsave(&chip->lock, flags); + /* If the mask says the pin should be GPO, we return from here */ + if (mask[offset] == AMD_GPIO_MODE_RESV) { + pr_info("GPIO %u is reserved\n", offset); + spin_unlock_irqrestore(&chip->lock, flags); + return -EINVAL; + } + + if (mask[offset] == AMD_GPIO_MODE_OUTPUT) { + pr_info("GPIO %u can only be set in input mode\n", offset); + spin_unlock_irqrestore(&chip->lock, flags); + return -EINVAL; + } + + gpio_reg = ioread32((u32 *)amd_gpio_chip.gpiobase + offset); + /* Disable output by set the bit to 0 */ + gpio_reg &= ~AMD_GPIO_OUTPUT_ENABLE; + /* enable or disable sw input */ + if(value) + gpio_reg |= AMD_GPIO_SWCTRL_IN; + else + gpio_reg &= ~AMD_GPIO_SWCTRL_IN; + + iowrite32(gpio_reg, ((u32 *)amd_gpio_chip.gpiobase + offset)); + spin_unlock_irqrestore(&chip->lock, flags); + + return 0; +} + + +static int gpio_test_open(struct inode *inode, struct file *filp) +{ + struct gpio_test_dev *dev; /* device information */ + + dev = container_of(inode->i_cdev, struct gpio_test_dev, cdev); + filp->private_data = dev; /* for other methods */ + + return 0; /* success */ +} + +static int gpio_test_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +static long gpio_test_ioctl(struct file *filp, + unsigned cmd, unsigned long arg) +{ + + debug_data tmp; + unsigned long retval = 0; + + /* Check type and command number */ + if (_IOC_TYPE(cmd) != GPIO_TEST_IOC_MAGIC) + return -ENOTTY; + + retval = copy_from_user(&tmp, (void __user *)arg, sizeof(debug_data)); + if(retval != 0) + return 0; + + switch(cmd) { + case GPIO_IOC_SWCTRLIN: + retval = amd_gpio_swctrlin(tmp.offset,tmp.value); + break; + case GPIO_IOC_SWCTRLEN: + retval = amd_gpio_swctrlen(tmp.offset,tmp.value); + break; + default: + return -ENOTTY; + } + + return retval; +} + +struct file_operations gpio_test_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = gpio_test_ioctl, + .open = gpio_test_open, + .release = gpio_test_release, +}; + + +static int __init amd_gpio_init_module(void) +{ + int err; + dev_t dev = 0; + struct device *gpio_device = 0; + + pr_info("AMD GPIO Driver v%s\n", GPIO_VERSION); + + err = platform_driver_register(&amd_gpio_driver); + if (err) + return err; + + err = alloc_chrdev_region(&dev, dev_minor, 1,"gpio_test_driver"); + if (err < 0) { + printk(KERN_WARNING " can't get major %d\n", dev_major); + goto unreg_platform_driver; + } + + gpio_test_dev.gpio_class = class_create(THIS_MODULE, "gpio_test_driver"); + if (IS_ERR(gpio_test_dev.gpio_class)) { + printk(" error in class create \n"); + goto unregister_test_driver; + } + + dev_major = MAJOR(dev); + + gpio_device = device_create(gpio_test_dev.gpio_class, NULL, dev, NULL, + "gpio_test_driver"); + if (IS_ERR(gpio_device)) { + printk(" error in device create \n"); + goto destroy_class; + } + + cdev_init(&gpio_test_dev.cdev, &gpio_test_fops); + err = cdev_add (&gpio_test_dev.cdev, dev, 1); + if(err) + goto destroy_device; + + amd_gpio_platform_device = platform_device_register_simple( + GPIO_MODULE_NAME, -1, NULL, 0); + if (IS_ERR(amd_gpio_platform_device)) { + err = PTR_ERR(amd_gpio_platform_device); + goto cdev_delete; + } + + return 0; + +cdev_delete: + cdev_del(&gpio_test_dev.cdev); +destroy_device: + device_destroy(gpio_test_dev.gpio_class, dev); +destroy_class: + class_destroy(gpio_test_dev.gpio_class); +unregister_test_driver: + unregister_chrdev_region(dev, 1); +unreg_platform_driver: + platform_driver_unregister(&amd_gpio_driver); + return err; +} + +static void __exit amd_gpio_cleanup_module(void) +{ + dev_t dev = MKDEV(dev_major, dev_minor); + + device_destroy(gpio_test_dev.gpio_class, dev); + class_destroy(gpio_test_dev.gpio_class); + cdev_del(&gpio_test_dev.cdev); + unregister_chrdev_region(dev, 1); + platform_device_unregister(amd_gpio_platform_device); + platform_driver_unregister(&amd_gpio_driver); + pr_info("AMD GPIO Module Unloaded\n"); +} + +module_init(amd_gpio_init_module); +module_exit(amd_gpio_cleanup_module); + + + +MODULE_AUTHOR("Sudheesh Mavila <sudheesh.mavila@amd.com>"); +MODULE_DESCRIPTION("GPIO driver for AMD chipsets"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/meta-steppeeagle/recipes-kernel/amd-gpio/files/gpio-amd.h b/meta-steppeeagle/recipes-kernel/amd-gpio/files/gpio-amd.h new file mode 100644 index 00000000..5574ef53 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-gpio/files/gpio-amd.h @@ -0,0 +1,85 @@ +#ifndef _AMD_GPIO_H_ +#define _AMD_GPIO_H_ + +#include <linux/types.h> + +/* Module and version information */ +#define GPIO_VERSION "0.1" +#define GPIO_MODULE_NAME "AMD GPIO" +#define GPIO_DRIVER_NAME GPIO_MODULE_NAME ", v" GPIO_VERSION + +#define DRV_NAME "amd-gpio" + +/* GPIO register definitions */ +#define AMD_GPIO_ACPIMMIO_BASE 0xFED80000 +#define AMD_GPIO_BANK_OFFSET 0x1500 +#define AMD_GPIO_MEM_MAP_SIZE 0x300 +#define AMD_GPIO_MSWITCH 63 + +#define AMD_IOMUX_MEM_MAP_OFFSET 0x0D00 +#define AMD_IOMUX_MEM_MAP_SIZE 0x100 + +#define AMD_PM_IOPORTS_SIZE 0x02 + +/* IO port address for indirect access using the ACPI PM registers */ +#define AMD_IO_PM_INDEX_REG 0xCD6 +#define AMD_IO_PM_DATA_REG 0xCD7 + +#define AMD_GPIO_NUM_PINS 184 + +#define AMD_GPIO_DEB_TIMEOUT0 (0) /* debouncing logic disabled */ +#define AMD_GPIO_DEB_TIMEOUT1 (1) +#define AMD_GPIO_DEB_TIMEOUT_MASK (7) +#define AMD_GPIO_DEB_TIMEOUTUNIT (1 << 4) +#define AMD_GPIO_DEB_CTRL (3 << 5) +#define AMD_GPIO_LEVL_TRG (1 << 8) /* 0 - edge , 1 level */ +#define AMD_GPIO_ACTIVE_LEVEL (3 << 9) +#define AMD_GPIO_INTERPT_ENABLE (3 << 11) +#define AMD_GPIO_WAKECTRL (7 << 13) +#define AMD_GPIO_GET_INPUT (1 << 16) +#define AMD_GPIO_DRV_STRENGTH(x) (((x) & 3) << 17) +#define AMD_GPIO_PULLUP_SEL (1 << 19) +#define AMD_GPIO_PULLUP_ENABLE (1 << 20) +#define AMD_GPIO_PULLDN_ENABLE (1 << 21) +#define AMD_GPIO_SET_OUTPUT (1 << 22) +#define AMD_GPIO_OUTPUT_ENABLE (1 << 23) +#define AMD_GPIO_SWCTRL_IN (1 << 24) +#define AMD_GPIO_SWCTRL_EN (1 << 25) +#define AMD_GPIO_INTERPT_STATUS (1 << 28) +#define AMD_GPIO_WAKE_STATUS (1 << 29) + +#define AMD_GPIO_WAKE_EN (1 << 31) +#define AMD_GPIO_INTERRUPT_EN (1 << 30) + +#define AMD_IOMUX_ENABLE_FUNC0 0x0 +#define AMD_IOMUX_ENABLE_FUNC1 0x1 +#define AMD_IOMUX_ENABLE_FUNC2 0x2 +#define AMD_IOMUX_ENABLE_FUNC3 0x3 +#define AMD_IOMUX_GPIO_MASK 0x03 + +#define AMD_PM_GPIO_BASE0 0x24 +#define AMD_PM_GPIO_BASE1 0x25 +#define AMD_PM_GPIO_BASE2 0x26 +#define AMD_PM_GPIO_BASE3 0x27 + + + + +/* GPIO pin mode definitions */ +#define AMD_GPIO_MODE_RESV 0 /* Reserved */ +#define AMD_GPIO_MODE_ANY 1 /* Either input or output */ +#define AMD_GPIO_MODE_INPUT 2 /* GPI */ +#define AMD_GPIO_MODE_OUTPUT 3 /* GPO */ + +/* IOCTL numbers */ + +typedef struct { + int offset; + int value; +}debug_data; + +#define GPIO_TEST_IOC_MAGIC 'k' +#define GPIO_IOC_SWCTRLIN _IOW(GPIO_TEST_IOC_MAGIC, 1, debug_data) +#define GPIO_IOC_SWCTRLEN _IOW(GPIO_TEST_IOC_MAGIC, 2, debug_data) + +#endif /* _AMD_GPIO_H_ */ diff --git a/meta-steppeeagle/recipes-kernel/amd-spi/amd-spi_1.0.bb b/meta-steppeeagle/recipes-kernel/amd-spi/amd-spi_1.0.bb new file mode 100644 index 00000000..f4304d4d --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-spi/amd-spi_1.0.bb @@ -0,0 +1,33 @@ +DESCRIPTION = "This kernel module provides support for AMD SPI controller driver" +LICENSE = "BSD | GPLv2" +LIC_FILES_CHKSUM = "file://spi_amd.c;md5=3cbc6410f1e2b6009f1a74731f6fc557 \ + file://spi_amd.h;md5=2233c2a926f120b07153e3ea0ba7474f \ + file://spirom.c;md5=1f5bba5ab39fb0759286aab09b55bc84 \ + file://spirom.h;md5=56f117ed31b82b02182c7a491364d112 \ + file://Makefile;md5=8ea80a6d4ae15bcf922d090df6cfdd4c \ + " + +inherit module + +PR = "r0" +PV = "1.0" + +SRC_URI = "file://Makefile \ + file://spi_amd.c \ + file://spi_amd.h \ + file://spirom.c \ + file://spirom.h \ + " + +S = "${WORKDIR}" + + +# Kernel module packages MUST begin with 'kernel-module-', otherwise +# multilib image generation can fail. +# +# The following line is only necessary if the recipe name does not begin +# with kernel-module-. +# +PKG_${PN} = "kernel-module-${PN}" + +FILES_${PN} += "${sysconfdir}" diff --git a/meta-steppeeagle/recipes-kernel/amd-spi/files/Makefile b/meta-steppeeagle/recipes-kernel/amd-spi/files/Makefile new file mode 100644 index 00000000..f778a69a --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-spi/files/Makefile @@ -0,0 +1,14 @@ +obj-m := spi_amd.o spirom.o + +SRC := $(shell pwd) + +all: + $(MAKE) -C $(KERNEL_SRC) M=$(SRC) + +modules_install: + $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install + +clean: + rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c + rm -f Module.markers Module.symvers modules.order + rm -rf .tmp_versions Modules.symvers diff --git a/meta-steppeeagle/recipes-kernel/amd-spi/files/spi_amd.c b/meta-steppeeagle/recipes-kernel/amd-spi/files/spi_amd.c new file mode 100644 index 00000000..554bd352 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-spi/files/spi_amd.c @@ -0,0 +1,492 @@ +/***************************************************************************** +* +* Copyright (c) 2014, Advanced Micro Devices, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Advanced Micro Devices, Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +***************************************************************************/ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/spi/spi.h> +#include <linux/kthread.h> + +#include "spi_amd.h" + +struct amd_platform_data { + u8 chip_select; +}; + +struct amd_spi { + void __iomem *io_remap_addr; + unsigned long io_base_addr; + u32 rom_addr; + struct spi_master *master; + struct amd_platform_data controller_data; + spinlock_t lock; + struct task_struct *kthread_spi; + struct list_head msg_queue; +}; + +static struct pci_device_id amd_spi_pci_device_id[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LPC_BRIDGE) }, + {} +}; +MODULE_DEVICE_TABLE(pci, amd_spi_pci_device_id); + +static inline u8 amd_spi_readreg8(struct spi_master *master, int idx) +{ + struct amd_spi *amd_spi = spi_master_get_devdata(master); + + return ioread8((u8 *)amd_spi->io_remap_addr + idx); +} + +static inline void amd_spi_writereg8(struct spi_master *master, int idx, + u8 val) +{ + struct amd_spi *amd_spi = spi_master_get_devdata(master); + + iowrite8(val, ((u8 *)amd_spi->io_remap_addr + idx)); +} + +static inline void amd_spi_setclear_reg8(struct spi_master *master, int idx, + u8 set, u8 clear) +{ + u8 tmp = amd_spi_readreg8(master, idx); + tmp = (tmp & ~clear) | set; + amd_spi_writereg8(master, idx, tmp); +} + +static inline u32 amd_spi_readreg32(struct spi_master *master, int idx) +{ + struct amd_spi *amd_spi = spi_master_get_devdata(master); + + return ioread32((u8 *)amd_spi->io_remap_addr + idx); +} + +static inline void amd_spi_writereg32(struct spi_master *master, int idx, + u32 val) +{ + struct amd_spi *amd_spi = spi_master_get_devdata(master); + + iowrite32(val, ((u8 *)amd_spi->io_remap_addr + idx)); +} + +static inline void amd_spi_setclear_reg32(struct spi_master *master, int idx, + u32 set, u32 clear) +{ + u32 tmp = amd_spi_readreg32(master, idx); + tmp = (tmp & ~clear) | set; + amd_spi_writereg32(master, idx, tmp); +} + +static void amd_spi_select_chip(struct spi_master *master) +{ + struct amd_spi *amd_spi = spi_master_get_devdata(master); + u8 chip_select = amd_spi->controller_data.chip_select; + + amd_spi_setclear_reg8(master, AMD_SPI_ALT_CS_REG, chip_select, + AMD_SPI_ALT_CS_MASK); +} + + +static void amd_spi_clear_fifo_ptr(struct spi_master *master) +{ + amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, AMD_SPI_FIFO_CLEAR, + AMD_SPI_FIFO_CLEAR); +} + +static void amd_spi_set_opcode(struct spi_master *master, u8 cmd_opcode) +{ + amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, cmd_opcode, + AMD_SPI_OPCODE_MASK); +} + +static inline void amd_spi_set_rx_count(struct spi_master *master, + u8 rx_count) +{ + amd_spi_setclear_reg8(master, AMD_SPI_RX_COUNT_REG, rx_count, 0xff); +} + +static inline void amd_spi_set_tx_count(struct spi_master *master, + u8 tx_count) +{ + amd_spi_setclear_reg8(master, AMD_SPI_TX_COUNT_REG, tx_count, 0xff); +} + +static void amd_spi_execute_opcode(struct spi_master *master) +{ + struct amd_spi *amd_spi = spi_master_get_devdata(master); + bool spi_busy; + + /* Set ExecuteOpCode bit in the CTRL0 register */ + amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, AMD_SPI_EXEC_CMD, + AMD_SPI_EXEC_CMD); + + /* poll for SPI bus to become idle */ + spi_busy = (ioread32((u8 *)amd_spi->io_remap_addr + + AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) == AMD_SPI_BUSY; + while (spi_busy) { + schedule(); + spi_busy = (ioread32((u8 *)amd_spi->io_remap_addr + + AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) == AMD_SPI_BUSY; + } +} + +/* Helper function */ +#ifdef CONFIG_SPI_DEBUG +static void amd_spi_dump_reg(struct spi_master *master) +{ + struct amd_spi *amd_spi = spi_master_get_devdata(master); + + printk(KERN_DEBUG DRIVER_NAME ": SPI CTRL 0 registers: 0x%.8x\n", + ioread32((u8 *)amd_spi->io_remap_addr + AMD_SPI_CTRL0_REG)); + /* + * We cannot read CTRL1 register, because reading it would + * inadvertently increment the FIFO pointer. + */ + printk(KERN_DEBUG DRIVER_NAME ": SPI ALT CS registers: 0x%.2x\n", + ioread8((u8 *)amd_spi->io_remap_addr + AMD_SPI_ALT_CS_REG)); + printk(KERN_DEBUG DRIVER_NAME ": SPI Tx Byte Count: 0x%.2x\n", + ioread8((u8 *)amd_spi->io_remap_addr + AMD_SPI_TX_COUNT_REG)); + printk(KERN_DEBUG DRIVER_NAME ": SPI Rx Byte Count: 0x%.2x\n", + ioread8((u8 *)amd_spi->io_remap_addr + AMD_SPI_RX_COUNT_REG)); + printk(KERN_DEBUG DRIVER_NAME ": SPI Status registers: 0x%.8x\n", + ioread32((u8 *)amd_spi->io_remap_addr + AMD_SPI_STATUS_REG)); +} +#else +static void amd_spi_dump_reg(struct spi_master *master) {} +#endif + + +static int amd_spi_master_setup(struct spi_device *spi) +{ + struct spi_master *master = spi->master; + struct amd_spi *amd_spi = spi_master_get_devdata(master); + + amd_spi->controller_data.chip_select = spi->chip_select; + + amd_spi_select_chip(master); + + return 0; +} + +static int amd_spi_master_transfer(struct spi_device *spi, + struct spi_message *msg) +{ + struct spi_master *master = spi->master; + struct amd_spi *amd_spi = spi_master_get_devdata(master); + + /* + * We will just add this message to the message queue set up by + * the controller, and let the kernel thread handle it later. + */ + msg->status = -EINPROGRESS; + msg->actual_length = 0; + msg->spi = spi; + /* + * There could be a situation when we are running on this processor + * and trying to add element to the end of the message queue, but + * at the same time the kernel thread is running on another processor + * and trying to find out if the list is empty or not. So protect + * against such contention. Simple spin_lock() should do. + */ + spin_lock(&amd_spi->lock); + list_add_tail(&msg->queue, &amd_spi->msg_queue); + spin_unlock(&amd_spi->lock); + + return 0; +} +static int amd_spi_thread(void *t) +{ + struct amd_spi *amd_spi = t; + struct spi_master *master = amd_spi->master; + struct spi_transfer *transfer = NULL; + struct spi_message *message = NULL; + int direction = 0,i = 0,saved_index = 0; + int opcode_found = 0,recv_flag = 0,tx_len = 0,rx_len = 0; + u8 cmd_opcode = 0; + u8 *buffer = NULL; + + /* + * What we do here is actually pretty simple. We pick one message + * at a time from the message queue set up by the controller, and + * then process all the spi_transfers of that spi_message in one go. + * We then remove the message from the queue, and complete the + * transaction. This might not be the best approach, but this is how + * we chose to implement this. Note that out SPI controller has FIFO + * size of 70 bytes, but we consider it to contain a maximum of + * 64-bytes of data and 3-bytes of address. + */ + while (1) { + /* break condition */ + if (kthread_should_stop()) { + set_current_state(TASK_RUNNING); + break; + } + + /* + * If the message queue is empty, then there is no need to waste + * CPU cycles. So we let other processes execute, and continue + * from the beginning of the loop when we next get to run. + */ + spin_lock(&amd_spi->lock); + if (list_empty(&amd_spi->msg_queue)) { + spin_unlock(&amd_spi->lock); + schedule(); + continue; + } + + /* + * Else, pull the very first message from the queue and process + * all transfers within that message. And process the messages + * in a pure linear fashion. We also remove the spi_message + * from the queue. + */ + message = list_entry(amd_spi->msg_queue.next, + struct spi_message, queue); + list_del_init(&message->queue); + spin_unlock(&amd_spi->lock); + + /* We store the CS# line to be used for this spi_message */ + amd_spi->controller_data.chip_select = + message->spi->chip_select; + + /* Setting all variables to default value. */ + direction = i = 0; + opcode_found = 0; + recv_flag = tx_len = rx_len = 0; + cmd_opcode = 0; + buffer = NULL; + saved_index = 0; + + amd_spi_select_chip(master); + + /* + * This loop extracts spi_transfers from the spi message, + * programs the command into command register. Pointer variable + * *buffer* points to either tx_buf or rx_buf of spi_transfer + * depending on direction of transfer. Also programs FIFO of + * controller if data has to be transmitted. + */ + list_for_each_entry(transfer, &message->transfers, + transfer_list) + { + if(transfer->rx_buf != NULL) + direction = RECEIVE; + else if(transfer->tx_buf != NULL) + direction = TRANSMIT; + + switch (direction) { + case TRANSMIT: + buffer = (u8 *)transfer->tx_buf; + + if(opcode_found != 1) { + /* Store no. of bytes to be sent into + * FIFO */ + tx_len = transfer->len - 1; + /* Store opcode */ + cmd_opcode = *(u8 *)transfer->tx_buf; + /* Pointing to start of TX data */ + buffer++; + /* Program the command register*/ + amd_spi_set_opcode(master, cmd_opcode); + opcode_found = 1; + } else { + /* Store no. of bytes to be sent into + * FIFO */ + tx_len = transfer->len; + } + + /* Write data into the FIFO. */ + for (i = 0; i < tx_len; i++) { + iowrite8(buffer[i], + ((u8 *)amd_spi->io_remap_addr + + AMD_SPI_FIFO_BASE + + i + saved_index)); + } + + /* Set no. of bytes to be transmitted */ + amd_spi_set_tx_count(master, + tx_len + saved_index); + + /* + * Saving the index, from where next + * spi_transfer's data will be stored in FIFO. + */ + saved_index = i; + break; + case RECEIVE: + /* Store no. of bytes to be received from + * FIFO */ + rx_len = transfer->len; + buffer = (u8 *)transfer->rx_buf; + recv_flag=1; + break; + } + } + + /* Set the RX count to the number of bytes to expect in + * response */ + amd_spi_set_rx_count(master, rx_len ); + amd_spi_clear_fifo_ptr(master); + amd_spi_dump_reg(master); + /* Executing command */ + amd_spi_execute_opcode(master); + amd_spi_dump_reg(master); + + if(recv_flag == 1) { + /* Read data from FIFO to receive buffer */ + for (i = 0; i < rx_len; i++) { + buffer[i] = ioread8((u8 *)amd_spi->io_remap_addr + + AMD_SPI_FIFO_BASE + + tx_len + i); + } + + recv_flag = 0; + } + + /* Update statistics */ + message->actual_length = tx_len + rx_len + 1 ; + /* complete the transaction */ + message->status = 0; + message->complete(message->context); + } + + return 0; +} + +static int amd_spi_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct device *dev = &pdev->dev; + struct spi_master *master; + struct amd_spi *amd_spi; + u32 io_base_addr; + int err = 0; + + /* Allocate storage for spi_master and driver private data */ + master = spi_alloc_master(dev, sizeof(struct amd_spi)); + if (master == NULL) { + dev_err(dev, "Error allocating SPI master\n"); + return -ENOMEM; + } + + amd_spi = spi_master_get_devdata(master); + amd_spi->master = master; + + /* + * Lets first get the base address of SPI registers. The SPI Base + * Address is stored at offset 0xA0 into the LPC PCI configuration + * space. As per the specification, it is stored at bits 6:31 of the + * register. The address is aligned at 64-byte boundary, + * so we should just mask the lower 6 bits and get the address. + */ + pci_read_config_dword(pdev, AMD_PCI_LPC_SPI_BASE_ADDR_REG, + &io_base_addr); + amd_spi->io_base_addr = io_base_addr & AMD_SPI_BASE_ADDR_MASK; + amd_spi->io_remap_addr = ioremap_nocache(amd_spi->io_base_addr, + AMD_SPI_MEM_SIZE); + if (amd_spi->io_remap_addr == NULL) { + dev_err(dev, "ioremap of SPI registers failed\n"); + err = -ENOMEM; + goto err_free_master; + } + dev_dbg(dev, "io_base_addr: 0x%.8lx, io_remap_address: %p\n", + amd_spi->io_base_addr, amd_spi->io_remap_addr); + spin_lock_init(&amd_spi->lock); + INIT_LIST_HEAD(&amd_spi->msg_queue); + amd_spi->kthread_spi = kthread_run(amd_spi_thread, amd_spi, + "amd_spi_thread"); + + /* Now lets initialize the fields of spi_master */ + master->bus_num = 0; /* + * This should be the same as passed in + * spi_board_info structure + */ + master->num_chipselect = 4; /* Can be overwritten later during setup */ + master->mode_bits = 0; + master->flags = 0; + master->setup = amd_spi_master_setup; + master->transfer = amd_spi_master_transfer; + /* Register the controller with SPI framework */ + err = spi_register_master(master); + if (err) { + dev_err(dev, "error registering SPI controller\n"); + goto err_iounmap; + } + pci_set_drvdata(pdev, amd_spi); + + return 0; + +err_iounmap: + iounmap(amd_spi->io_remap_addr); +err_free_master: + spi_master_put(master); + + return 0; +} + +static void amd_spi_pci_remove(struct pci_dev *pdev) +{ + struct amd_spi *amd_spi = pci_get_drvdata(pdev); + + kthread_stop(amd_spi->kthread_spi); + iounmap(amd_spi->io_remap_addr); + spi_unregister_master(amd_spi->master); + spi_master_put(amd_spi->master); + pci_set_drvdata(pdev, NULL); +} + +static struct pci_driver amd_spi_pci_driver = { + .name = "amd_spi", + .id_table = amd_spi_pci_device_id, + .probe = amd_spi_pci_probe, + .remove = amd_spi_pci_remove, +}; + +static int __init amd_spi_init(void) +{ + int ret; + + pr_info("AMD SPI Driver v%s\n", SPI_VERSION); + + ret = pci_register_driver(&amd_spi_pci_driver); + if (ret) + return ret; + + return 0; +} +module_init(amd_spi_init); + +static void __exit amd_spi_exit(void) +{ + pci_unregister_driver(&amd_spi_pci_driver); +} +module_exit(amd_spi_exit); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Arindam Nath <arindam.nath@amd.com>"); +MODULE_DESCRIPTION("AMD SPI Master Controller Driver"); diff --git a/meta-steppeeagle/recipes-kernel/amd-spi/files/spi_amd.h b/meta-steppeeagle/recipes-kernel/amd-spi/files/spi_amd.h new file mode 100644 index 00000000..ea5181d7 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-spi/files/spi_amd.h @@ -0,0 +1,28 @@ +#ifndef SPI_AMD_H +#define SPI_AMD_H + +#define DRIVER_NAME "spi_amd" +#define SPI_VERSION "0.1" + +#define AMD_SPI_CTRL0_REG 0x00 + #define AMD_SPI_EXEC_CMD (0x1 << 16) + #define AMD_SPI_OPCODE_MASK 0xFF + #define AMD_SPI_FIFO_CLEAR (0x1 << 20) + #define AMD_SPI_BUSY (0x1 << 31) +#define AMD_SPI_ALT_CS_REG 0x1D + #define AMD_SPI_ALT_CS_MASK 0x3 +#define AMD_SPI_FIFO_BASE 0x80 +#define AMD_SPI_TX_COUNT_REG 0x48 +#define AMD_SPI_RX_COUNT_REG 0x4B +#define AMD_SPI_STATUS_REG 0x4C + +#define AMD_PCI_LPC_SPI_BASE_ADDR_REG 0xA0 +#define AMD_SPI_BASE_ADDR_MASK ~0x3F +#define AMD_SPI_MEM_SIZE 200 + +#define PCI_DEVICE_ID_AMD_LPC_BRIDGE 0x780E + +#define TRANSMIT 1 +#define RECEIVE 2 + +#endif /* SPI_AMD_H */ diff --git a/meta-steppeeagle/recipes-kernel/amd-spi/files/spirom.c b/meta-steppeeagle/recipes-kernel/amd-spi/files/spirom.c new file mode 100644 index 00000000..439961bc --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-spi/files/spirom.c @@ -0,0 +1,516 @@ +/***************************************************************************** +* +* spirom.c - SPI ROM client driver +* +* Copyright (c) 2014, Advanced Micro Devices, Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* 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, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +* +***************************************************************************/ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/ioctl.h> +#include <linux/fs.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/list.h> +#include <linux/errno.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/spi/spi.h> +#include <asm/uaccess.h> + +#include "spirom.h" + +#define SPIROM_VERSION "0.1" + +/* + * SPI has a character major number assigned. We allocate minor numbers + * dynamically using a bitmask. You must use hotplug tools, such as udev + * (or mdev with busybox) to create and destroy the /dev/spiromB.C device + * nodes, since there is no fixed association of minor numbers with any + * particular SPI bus or device. + */ +#define SPIROM_MAJOR 153 /* assigned */ +#define N_SPI_MINORS 32 /* ... up to 256 */ + +#define SPI_BUS 0 +#define SPI_BUS_CS1 0 + +static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; + + +struct spirom_data { + dev_t devt; + spinlock_t spi_lock; + struct spi_device *spi; + struct list_head device_entry; + struct completion done; + + struct mutex buf_lock; + unsigned users; +}; + +static LIST_HEAD(device_list); +static DEFINE_MUTEX(device_list_lock); + +/*-------------------------------------------------------------------------*/ + +/* + * We can't use the standard synchronous wrappers for file I/O; we + * need to protect against async removal of the underlying spi_device. + */ +static void spirom_complete(void *arg) +{ + complete(arg); +} + +static ssize_t +spirom_sync(struct spirom_data *spirom, struct spi_message *message) +{ + int status; + + message->complete = spirom_complete; + message->context = &spirom->done; + + spin_lock_irq(&spirom->spi_lock); + if (spirom->spi == NULL) + status = -ESHUTDOWN; + else + status = spi_async(spirom->spi, message); + spin_unlock_irq(&spirom->spi_lock); + + if (status == 0) { + /* + * There might be cases where the controller driver has been + * unloaded in the middle of a transaction. So we might end up + * in a situation where we will be waiting for an event which + * will never happen. So we provide a timeout of 1 second for + * situations like this. + */ + wait_for_completion_timeout(&spirom->done, HZ); + status = message->status; + if (status == 0) + status = message->actual_length; + } + return status; +} + +static int spirom_message(struct spirom_data *spirom, + struct spi_ioc_transfer *u_trans, unsigned long arg) +{ + struct spi_message msg; + struct spi_transfer *transfer; + u8 *buffer; + int status = u_trans->len; + + buffer = u_trans->buf; + spi_message_init(&msg); + + /* The very first spi_transfer will contain the command only */ + transfer = kzalloc(sizeof(struct spi_transfer), GFP_KERNEL); + if (!transfer) + return -ENOMEM; + + transfer->tx_buf = buffer; + transfer->len = 1; + buffer += transfer->len; + spi_message_add_tail(transfer, &msg); + + /* + * If the command expects an address as its argument, we populate + * it in the very next spi_transfer. + */ + if (u_trans->addr_present) { + transfer = kzalloc(sizeof(struct spi_transfer), GFP_KERNEL); + if (!transfer) + return -ENOMEM; + + transfer->tx_buf = buffer; + transfer->len = 3; // 3-byte address + buffer += transfer->len; + spi_message_add_tail(transfer, &msg); + } + + /* + * Next is data, which can have a maximum of 64-bytes, the size limited + * by the number of bytes that can stored in the controller FIFO. + */ + if (u_trans->len) { + transfer = kzalloc(sizeof(struct spi_transfer), GFP_KERNEL); + if (!transfer) + return -ENOMEM; + + if (u_trans->direction == TRANSMIT) + transfer->tx_buf = buffer; + else if (u_trans->direction == RECEIVE) + transfer->rx_buf = buffer; + + transfer->len = u_trans->len; + /* No need to increment buffer pointer */ + spi_message_add_tail(transfer, &msg); + } + + status = spirom_sync(spirom, &msg); + + if (u_trans->direction == RECEIVE) { + /* + * The received data should have been populated in + * u_trans->buf, so we just need to copy it into the + * user-space buffer. + */ + buffer = u_trans->buf; + if (u_trans->addr_present) { + buffer += 4; // 1-byte command and 3-byte address + if(__copy_to_user((u8 __user *) + (((struct spi_ioc_transfer *)arg)->buf) + 4, + buffer, u_trans->len)) { + status = -EFAULT; + } + } else { + buffer += 1; // 1-byte command only + if(__copy_to_user((u8 __user *) + (((struct spi_ioc_transfer *)arg)->buf) + 1, + buffer, u_trans->len)) { + status = -EFAULT; + } + } + } + + /* Done with everything, free the memory taken by spi_transfer */ + while (msg.transfers.next != &msg.transfers) { + transfer = list_entry(msg.transfers.next, struct spi_transfer, + transfer_list); + msg.transfers.next = transfer->transfer_list.next; + transfer->transfer_list.next->prev = &msg.transfers; + kfree(transfer); + } + + return status; +} + +static long +spirom_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int err = 0; + int retval = 0; + struct spirom_data *spirom; + struct spi_device *spi; + u32 tmp; + struct spi_ioc_transfer *ioc; + + /* Check type and command number */ + if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC) + return -ENOTTY; + + /* Check access direction once here; don't repeat below. + * IOC_DIR is from the user perspective, while access_ok is + * from the kernel perspective; so they look reversed. + */ + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, + (void __user *)arg, _IOC_SIZE(cmd)); + if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, + (void __user *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + /* guard against device removal before, or while, + * we issue this ioctl. + */ + spirom = filp->private_data; + spin_lock_irq(&spirom->spi_lock); + spi = spi_dev_get(spirom->spi); + spin_unlock_irq(&spirom->spi_lock); + + if (spi == NULL) + return -ESHUTDOWN; + + /* use the buffer lock here for triple duty: + * - prevent I/O (from us) so calling spi_setup() is safe; + * - prevent concurrent SPI_IOC_WR_* from morphing + * data fields while SPI_IOC_RD_* reads them; + * - SPI_IOC_MESSAGE needs the buffer locked "normally". + */ + mutex_lock(&spirom->buf_lock); + + /* segmented and/or full-duplex I/O request */ + if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) || + _IOC_DIR(cmd) !=_IOC_WRITE) { + retval = -ENOTTY; + goto out; + } + + tmp = sizeof(struct spi_ioc_transfer); + + /* copy into scratch area */ + ioc = kzalloc(tmp, GFP_KERNEL); + if (!ioc) { + retval = -ENOMEM; + goto out; + } + if (__copy_from_user(ioc, (struct spi_ioc_transfer __user *)arg, + tmp)) { + kfree(ioc); + retval = -EFAULT; + goto out; + } + + /* translate to spi_message, execute */ + retval = spirom_message(spirom, ioc, arg); + kfree(ioc); + +out: + mutex_unlock(&spirom->buf_lock); + spi_dev_put(spi); + return retval; +} + +static int spirom_open(struct inode *inode, struct file *filp) +{ + struct spirom_data *spirom; + int status = -ENXIO; + + mutex_lock(&device_list_lock); + + list_for_each_entry(spirom, &device_list, device_entry) { + if (spirom->devt == inode->i_rdev) { + status = 0; + break; + } + } + if (status == 0) { + if (status == 0) { + spirom->users++; + filp->private_data = spirom; + nonseekable_open(inode, filp); + } + } else + pr_debug("spirom: nothing for minor %d\n", iminor(inode)); + + mutex_unlock(&device_list_lock); + return status; +} + +static int spirom_release(struct inode *inode, struct file *filp) +{ + struct spirom_data *spirom; + int status = 0; + + mutex_lock(&device_list_lock); + spirom = filp->private_data; + filp->private_data = NULL; + + /* last close? */ + spirom->users--; + if (!spirom->users) { + int dofree; + + /* ... after we unbound from the underlying device? */ + spin_lock_irq(&spirom->spi_lock); + dofree = (spirom->spi == NULL); + spin_unlock_irq(&spirom->spi_lock); + + if (dofree) + kfree(spirom); + } + mutex_unlock(&device_list_lock); + + return status; +} + +static const struct file_operations spirom_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = spirom_ioctl, + .open = spirom_open, + .release = spirom_release, +}; + +static int __init add_spi_device_to_bus(void) +{ + struct spi_master *spi_master; + struct spi_device *spi_device; + struct spi_board_info spi_info; + + spi_master = spi_busnum_to_master(SPI_BUS); + if (!spi_master) { + printk(KERN_ALERT "Please make sure to \'modprobe " + "spi_amd\' driver first\n"); + return -1; + } + memset(&spi_info, 0, sizeof(struct spi_board_info)); + + strlcpy(spi_info.modalias, "spirom", SPI_NAME_SIZE); + spi_info.bus_num = SPI_BUS; //Bus number of SPI master + spi_info.chip_select = SPI_BUS_CS1; //CS on which SPI device is connected + + spi_device = spi_new_device(spi_master, &spi_info); + if (!spi_device) + return -ENODEV; + + return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* The main reason to have this class is to make mdev/udev create the + * /dev/spiromB.C character device nodes exposing our userspace API. + * It also simplifies memory management. + */ + +static struct class *spirom_class; + +/*-------------------------------------------------------------------------*/ + +static int spirom_probe(struct spi_device *spi) +{ + struct spirom_data *spirom; + int status; + unsigned long minor; + + /* Allocate driver data */ + spirom = kzalloc(sizeof(*spirom), GFP_KERNEL); + if (!spirom) + return -ENOMEM; + + /* Initialize the driver data */ + spirom->spi = spi; + spin_lock_init(&spirom->spi_lock); + mutex_init(&spirom->buf_lock); + + INIT_LIST_HEAD(&spirom->device_entry); + init_completion(&spirom->done); + + /* If we can allocate a minor number, hook up this device. + * Reusing minors is fine so long as udev or mdev is working. + */ + mutex_lock(&device_list_lock); + minor = find_first_zero_bit(minors, N_SPI_MINORS); + if (minor < N_SPI_MINORS) { + struct device *dev; + + spirom->devt = MKDEV(SPIROM_MAJOR, minor); + dev = device_create(spirom_class, &spi->dev, spirom->devt, + spirom, "spirom%d.%d", + spi->master->bus_num, spi->chip_select); + status = IS_ERR(dev) ? PTR_ERR(dev) : 0; + } else { + dev_dbg(&spi->dev, "no minor number available!\n"); + status = -ENODEV; + } + if (status == 0) { + set_bit(minor, minors); + list_add(&spirom->device_entry, &device_list); + } + mutex_unlock(&device_list_lock); + + if (status == 0) + spi_set_drvdata(spi, spirom); + else + kfree(spirom); + + return status; +} + +static int spirom_remove(struct spi_device *spi) +{ + struct spirom_data *spirom = spi_get_drvdata(spi); + + /* make sure ops on existing fds can abort cleanly */ + spin_lock_irq(&spirom->spi_lock); + spirom->spi = NULL; + spi_set_drvdata(spi, NULL); + spin_unlock_irq(&spirom->spi_lock); + + /* prevent new opens */ + mutex_lock(&device_list_lock); + list_del(&spirom->device_entry); + clear_bit(MINOR(spirom->devt), minors); + device_destroy(spirom_class, spirom->devt); + if (spirom->users == 0) + kfree(spirom); + mutex_unlock(&device_list_lock); + + return 0; +} + +static struct spi_driver spirom_spi = { + .driver = { + .name = "spirom", + .owner = THIS_MODULE, + }, + .probe = spirom_probe, + .remove = spirom_remove, + + /* NOTE: suspend/resume methods are not necessary here. + * We don't do anything except pass the requests to/from + * the underlying controller. The refrigerator handles + * most issues; the controller driver handles the rest. + */ +}; + +/*-------------------------------------------------------------------------*/ + +static int __init spirom_init(void) +{ + int status; + + pr_info("AMD SPIROM Driver v%s\n", SPIROM_VERSION); + + /* Claim our 256 reserved device numbers. Then register a class + * that will key udev/mdev to add/remove /dev nodes. Last, register + * the driver which manages those device numbers. + */ + BUILD_BUG_ON(N_SPI_MINORS > 256); + status = register_chrdev(SPIROM_MAJOR, "spi", &spirom_fops); + if (status < 0) + return status; + + spirom_class = class_create(THIS_MODULE, "spirom"); + if (IS_ERR(spirom_class)) { + unregister_chrdev(SPIROM_MAJOR, spirom_spi.driver.name); + return PTR_ERR(spirom_class); + } + + status = spi_register_driver(&spirom_spi); + if (status < 0) { + class_destroy(spirom_class); + unregister_chrdev(SPIROM_MAJOR, spirom_spi.driver.name); + } + + status = add_spi_device_to_bus(); + if (status < 0) { + spi_unregister_driver(&spirom_spi); + class_destroy(spirom_class); + unregister_chrdev(SPIROM_MAJOR, spirom_spi.driver.name); + } + + return status; +} +module_init(spirom_init); + +static void __exit spirom_exit(void) +{ + spi_unregister_driver(&spirom_spi); + class_destroy(spirom_class); + unregister_chrdev(SPIROM_MAJOR, spirom_spi.driver.name); +} +module_exit(spirom_exit); + +MODULE_AUTHOR("Arindam Nath <arindam.nath@amd.com>"); +MODULE_DESCRIPTION("User mode SPI ROM interface"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:spirom"); diff --git a/meta-steppeeagle/recipes-kernel/amd-spi/files/spirom.h b/meta-steppeeagle/recipes-kernel/amd-spi/files/spirom.h new file mode 100644 index 00000000..750719a6 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-spi/files/spirom.h @@ -0,0 +1,43 @@ +#ifndef SPIROM_H +#define SPIROM_H + +#include <linux/types.h> + +/*---------------------------------------------------------------------------*/ + +/* IOCTL commands */ + +#define SPI_IOC_MAGIC 'k' + +#define TRANSMIT 1 +#define RECEIVE 2 + +/* + * struct spi_ioc_transfer - interface structure between application and ioctl + * + * @buf: Buffer to hold 1-byte command, 3-bytes address, and 64-byte data for + * transmit or receive. The internal FIFO of our controller can hold a + * maximum of 70 bytes, including the address. But here we assume the + * maximum data excluding address to be 64-bytes long. + * + * @direction: Direction of data transfer, either TRANSMIT or RECEIVE. + * + * @len: Length of data excluding command and address. + * + * @addr_present: Flag to indicate whether 'buf' above contains an address. + */ +struct spi_ioc_transfer { + __u8 buf[64 + 1 + 3]; + __u8 direction; + __u8 len; + __u8 addr_present; +}; + +/* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */ +#define SPI_MSGSIZE(N) \ + ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ + ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0) +#define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) + + +#endif /* SPIROM_H */ diff --git a/meta-steppeeagle/recipes-kernel/amd-wdt/amd-wdt_1.0.bb b/meta-steppeeagle/recipes-kernel/amd-wdt/amd-wdt_1.0.bb new file mode 100644 index 00000000..22324c38 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-wdt/amd-wdt_1.0.bb @@ -0,0 +1,28 @@ +DESCRIPTION = "This kernel module provides support for AMD Watchdog driver" +LICENSE = "BSD | GPLv2" +LIC_FILES_CHKSUM = "file://amd_wdt.c;md5=8b8efe83eff938c6f17592973d38e70d \ + file://amd_wdt.h;md5=29c5be1a55c35b14a9bde439b9de839e \ + file://Makefile;md5=111ec65dfed99f6cd330ccb4957fb924 \ + " + +inherit module + +PR = "r0" +PV = "1.0" + +SRC_URI = "file://Makefile \ + file://amd_wdt.c \ + file://amd_wdt.h \ + " + +S = "${WORKDIR}" + +# Kernel module packages MUST begin with 'kernel-module-', otherwise +# multilib image generation can fail. +# +# The following line is only necessary if the recipe name does not begin +# with kernel-module-. +# +PKG_${PN} = "kernel-module-${PN}" + +FILES_${PN} += "${sysconfdir}" diff --git a/meta-steppeeagle/recipes-kernel/amd-wdt/files/Makefile b/meta-steppeeagle/recipes-kernel/amd-wdt/files/Makefile new file mode 100644 index 00000000..36b32f87 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-wdt/files/Makefile @@ -0,0 +1,14 @@ +obj-m := amd_wdt.o + +SRC := $(shell pwd) + +all: + $(MAKE) -C $(KERNEL_SRC) M=$(SRC) + +modules_install: + $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install + +clean: + rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c + rm -f Module.markers Module.symvers modules.order + rm -rf .tmp_versions Modules.symvers diff --git a/meta-steppeeagle/recipes-kernel/amd-wdt/files/amd_wdt.c b/meta-steppeeagle/recipes-kernel/amd-wdt/files/amd_wdt.c new file mode 100644 index 00000000..26da1736 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-wdt/files/amd_wdt.c @@ -0,0 +1,518 @@ +/***************************************************************************** +* +* Copyright (c) 2014, Advanced Micro Devices, Inc. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Advanced Micro Devices, Inc. nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* +***************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/types.h> +#include <linux/miscdevice.h> +#include <linux/watchdog.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <linux/platform_device.h> +#include <linux/uaccess.h> +#include <linux/io.h> + +#include "amd_wdt.h" + +/* internal variables */ +static u32 wdtbase_phys; +static void __iomem *wdtbase; +static DEFINE_SPINLOCK(wdt_lock); +static unsigned int bootstatus; +static unsigned long status; +static struct pci_dev *amd_wdt_pci; + +/* watchdog platform device */ +static struct platform_device *amd_wdt_platform_device; + +/* module parameters */ +static int heartbeat = WATCHDOG_HEARTBEAT; +module_param(heartbeat, int, 0); +MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in frequency units. " + "(default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); + +static char frequency[MAX_LENGTH] = "1s"; +module_param_string(frequency, frequency, MAX_LENGTH, 0); +MODULE_PARM_DESC(frequency, "Watchdog timer frequency units (32us, " + "10ms, 100ms, 1s). (default=1s)"); + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started" + " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +static char action[MAX_LENGTH] = "reboot"; +module_param_string(action, action, MAX_LENGTH, 0); +MODULE_PARM_DESC(action, "Watchdog action (reboot/shutdown). (default=reboot) "); + +/* + * Watchdog specific functions + */ +static int amd_wdt_timer_set_heartbeat(unsigned int t) +{ + unsigned long flags; + + /* + * In case the user inputs out of range timeout, we set it to the + * maximum timeout possible. + */ + if ((t == 0) || (t > 0xffff)) + heartbeat = t = 0xffff; + + /* Write new timeout value to watchdog */ + spin_lock_irqsave(&wdt_lock, flags); + writel(t, AMD_WDT_COUNT(wdtbase)); + spin_unlock_irqrestore(&wdt_lock, flags); + + heartbeat = t; + + return 0; +} + +static void amd_wdt_timer_activate(void) +{ + u32 val; + unsigned long flags; + + /* Enable the watchdog timer */ + spin_lock_irqsave(&wdt_lock, flags); + + val = readl(AMD_WDT_CONTROL(wdtbase)); + val |= AMD_WDT_START_STOP_BIT; + writel(val, AMD_WDT_CONTROL(wdtbase)); + + set_bit(AMD_WDOG_ACTIVE, &status); + + spin_unlock_irqrestore(&wdt_lock, flags); +} + +static void amd_wdt_timer_deactivate(void) +{ + u32 val; + unsigned long flags; + + /* Disable the watchdog timer */ + spin_lock_irqsave(&wdt_lock, flags); + + val = readl(AMD_WDT_CONTROL(wdtbase)); + val &= ~AMD_WDT_START_STOP_BIT; + writel(val, AMD_WDT_CONTROL(wdtbase)); + + clear_bit(AMD_WDOG_ACTIVE, &status); + + spin_unlock_irqrestore(&wdt_lock, flags); +} + +static void amd_wdt_timer_keepalive(void) +{ + u32 val; + unsigned long flags; + + /* Trigger watchdog */ + spin_lock_irqsave(&wdt_lock, flags); + + val = readl(AMD_WDT_CONTROL(wdtbase)); + val |= AMD_WDT_TRIGGER_BIT; + writel(val, AMD_WDT_CONTROL(wdtbase)); + + spin_unlock_irqrestore(&wdt_lock, flags); +} + +static unsigned int amd_wdt_timer_get_timeleft(void) +{ + u32 val; + unsigned long flags; + + spin_lock_irqsave(&wdt_lock, flags); + val = readl(AMD_WDT_COUNT(wdtbase)); + spin_unlock_irqrestore(&wdt_lock, flags); + + /* Mask out the upper 16-bits and return */ + return val & AMD_WDT_COUNT_MASK; +} + +static int amd_wdt_timer_open(struct inode *inode, struct file *file) +{ + /* /dev/watchdog can only be opened once */ + if (test_and_set_bit(AMD_WDOG_DEV_OPEN, &status)) + return -EBUSY; + + /* Start the watchdog timer and ping it once */ + amd_wdt_timer_activate(); + amd_wdt_timer_keepalive(); + + return nonseekable_open(inode, file); +} + +static int amd_wdt_timer_release(struct inode *inode, struct file *file) +{ + if (test_and_clear_bit(AMD_WDOG_ALLOW_RELEASE, &status)) { + amd_wdt_timer_deactivate(); + } else { + pr_crit("Unexpected close, not stopping watchdog!\n"); + amd_wdt_timer_keepalive(); + } + + clear_bit(AMD_WDOG_DEV_OPEN, &status); + + return 0; +} + +static ssize_t amd_wdt_timer_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + /* See if we got the magic character 'V' and reload the timer */ + if (len) { + if (!nowayout) { + size_t i; + + clear_bit(AMD_WDOG_ALLOW_RELEASE, &status); + + /* + * parse user buffer to see if we received magic + * character 'V'. + */ + for (i = 0; i != len; i++) { + char c; + + if (get_user(c, data + i)) + return -EFAULT; + + if (c == 'V') + set_bit(AMD_WDOG_ALLOW_RELEASE, &status); + } + } + + /* Reload the timer */ + amd_wdt_timer_keepalive(); + } + + return len; +} + +static long amd_wdt_timer_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int new_options, retval = -EINVAL; + int new_heartbeat; + int timeleft; + void __user *argp = (void __user *)arg; + int __user *p = argp; + static const struct watchdog_info ident = { + .options = WDIOF_SETTIMEOUT | + WDIOF_KEEPALIVEPING | + WDIOF_MAGICCLOSE, + .firmware_version = 0, + .identity = WDT_MODULE_NAME, + }; + + switch (cmd) { + case WDIOC_GETSUPPORT: + return copy_to_user(argp, &ident, + sizeof(ident)) ? -EFAULT : 0; + case WDIOC_GETSTATUS: + return put_user(status, p); + case WDIOC_GETBOOTSTATUS: + return put_user(bootstatus, p); + case WDIOC_SETOPTIONS: + if (get_user(new_options, p)) + return -EFAULT; + if (new_options & WDIOS_DISABLECARD) { + amd_wdt_timer_deactivate(); + retval = 0; + } + if (new_options & WDIOS_ENABLECARD) { + amd_wdt_timer_activate(); + amd_wdt_timer_keepalive(); + retval = 0; + } + return retval; + case WDIOC_KEEPALIVE: + amd_wdt_timer_keepalive(); + return 0; + case WDIOC_SETTIMEOUT: + if (get_user(new_heartbeat, p)) + return -EFAULT; + if (amd_wdt_timer_set_heartbeat(new_heartbeat)) + return -EINVAL; + amd_wdt_timer_keepalive(); + /* Fall through */ + case WDIOC_GETTIMEOUT: + return put_user(heartbeat, p); + case WDIOC_GETTIMELEFT: + timeleft = amd_wdt_timer_get_timeleft(); + return put_user(timeleft, p); + default: + return -ENOTTY; + } +} + +/* Watchdog timer file operations structure */ +static const struct file_operations amd_wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = amd_wdt_timer_write, + .unlocked_ioctl = amd_wdt_timer_ioctl, + .open = amd_wdt_timer_open, + .release = amd_wdt_timer_release, +}; + +static struct miscdevice amd_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &amd_wdt_fops, +}; + +/* + * The PCI Device ID table below is used to identify the platform + * the driver is supposed to work for. Since this is a platform + * device, we need a way for us to be able to find the correct + * platform when the driver gets loaded, otherwise we should + * bail out. + */ +static DEFINE_PCI_DEVICE_TABLE(amd_wdt_pci_tbl) = { + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, PCI_ANY_ID, + PCI_ANY_ID, }, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, amd_wdt_pci_tbl); + +static unsigned char amd_wdt_setupdevice(void) +{ + struct pci_dev *dev = NULL; + u32 val; + + /* Match the PCI device */ + for_each_pci_dev(dev) { + if (pci_match_id(amd_wdt_pci_tbl, dev) != NULL) { + amd_wdt_pci = dev; + break; + } + } + + if (!amd_wdt_pci) + return 0; + + /* Watchdog Base Address starts from ACPI MMIO Base Address + 0xB00 */ + wdtbase_phys = AMD_ACPI_MMIO_BASE + AMD_WDT_MEM_MAP_OFFSET; + if (!request_mem_region_exclusive(wdtbase_phys, AMD_WDT_MEM_MAP_SIZE, + "AMD Watchdog")) { + pr_err("mmio address 0x%04x already in use\n", wdtbase_phys); + goto exit; + } + + wdtbase = ioremap(wdtbase_phys, AMD_WDT_MEM_MAP_SIZE); + if (!wdtbase) { + pr_err("failed to get wdtbase address\n"); + goto unreg_mem_region; + } + + /* Enable watchdog timer and decode bit */ + outb(AMD_PM_WATCHDOG_EN_REG, AMD_IO_PM_INDEX_REG); + val = inb(AMD_IO_PM_DATA_REG); + val |= AMD_PM_WATCHDOG_TIMER_EN; + outb(val, AMD_IO_PM_DATA_REG); + + /* Set the watchdog timer resolution */ + outb(AMD_PM_WATCHDOG_CONFIG_REG, AMD_IO_PM_INDEX_REG); + val = inb(AMD_IO_PM_DATA_REG); + /* Clear the previous frequency setting, if any */ + val &= ~AMD_PM_WATCHDOG_CONFIG_MASK; + + /* + * Now set the frequency depending on the module load parameter. + * In case the user passes an invalid argument, we consider the + * frequency to be of 1 second resolution. + */ + if (strncmp(frequency, "32us", 4) == 0) + val |= AMD_PM_WATCHDOG_32USEC_RES; + else if (strncmp(frequency, "10ms", 4) == 0) + val |= AMD_PM_WATCHDOG_10MSEC_RES; + else if (strncmp(frequency, "100ms", 5) == 0) + val |= AMD_PM_WATCHDOG_100MSEC_RES; + else { + val |= AMD_PM_WATCHDOG_1SEC_RES; + if (strncmp(frequency, "1s", 2) != 0) + strncpy(frequency, "1s", 2); + } + + outb(val, AMD_IO_PM_DATA_REG); + + /* Set the watchdog action depending on module load parameter. */ + val = readl(AMD_WDT_CONTROL(wdtbase)); + + /* + * If action is specified anything other than reboot or shutdown, + * we default it to reboot. + */ + if (strncmp(action, "shutdown", 8) == 0) + val |= AMD_WDT_ACTION_RESET_BIT; + else { + val &= ~AMD_WDT_ACTION_RESET_BIT; + /* The statement below is required for when the action + * is set anything other than reboot. + */ + if (strncmp(action, "reboot", 6) != 0) + strncpy(action, "reboot", 6); + } + + writel(val, AMD_WDT_CONTROL(wdtbase)); + + return 1; + +unreg_mem_region: + release_mem_region(wdtbase_phys, AMD_WDT_MEM_MAP_SIZE); +exit: + return 0; +} + +static int amd_wdt_init(struct platform_device *dev) +{ + int ret; + u32 val; + + /* Identify our device and initialize watchdog hardware */ + if (!amd_wdt_setupdevice()) + return -ENODEV; + + /* Check to see if last reboot was due to watchdog timeout */ + val = readl(AMD_WDT_CONTROL(wdtbase)); + if (val & AMD_WDT_FIRED_BIT) + bootstatus |= WDIOF_CARDRESET; + else + bootstatus &= ~WDIOF_CARDRESET; + + pr_info("Watchdog reboot %sdetected\n", + (val & AMD_WDT_FIRED_BIT) ? "" : "not "); + + /* Clear out the old status */ + val |= AMD_WDT_FIRED_BIT; + writel(val, AMD_WDT_CONTROL(wdtbase)); + + /* Set Watchdog timeout */ + amd_wdt_timer_set_heartbeat(heartbeat); + + ret = misc_register(&amd_wdt_miscdev); + if (ret != 0) { + pr_err("Watchdog timer: cannot register miscdevice on minor=" + "%d (err=%d)\n", WATCHDOG_MINOR, ret); + goto exit; + } + + clear_bit(AMD_WDOG_DEV_OPEN, &status); + if (nowayout) + set_bit(AMD_WDOG_NO_WAY_OUT, &status); + + pr_info("initialized (0x%p). (heartbeat=%d units) (frequency=%s) " + "(nowayout=%d) (action=%s)\n", wdtbase, heartbeat, frequency, + nowayout, action); + + return 0; + +exit: + iounmap(wdtbase); + release_mem_region(wdtbase_phys, AMD_WDT_MEM_MAP_SIZE); + return ret; +} + +static void amd_wdt_cleanup(void) +{ + /* Stop the timer before we leave */ + if (!nowayout) + amd_wdt_timer_deactivate(); + + misc_deregister(&amd_wdt_miscdev); + iounmap(wdtbase); + release_mem_region(wdtbase_phys, AMD_WDT_MEM_MAP_SIZE); +} + +static int amd_wdt_remove(struct platform_device *dev) +{ + if (wdtbase) + amd_wdt_cleanup(); + + return 0; +} + +static void amd_wdt_shutdown(struct platform_device *dev) +{ + amd_wdt_timer_deactivate(); +} + +static struct platform_driver amd_wdt_driver = { + .probe = amd_wdt_init, + .remove = amd_wdt_remove, + .shutdown = amd_wdt_shutdown, + .driver = { + .owner = THIS_MODULE, + .name = WDT_MODULE_NAME, + }, +}; + +static int __init amd_wdt_init_module(void) +{ + int err; + + pr_info("AMD WatchDog Timer Driver v%s\n", WDT_VERSION); + + err = platform_driver_register(&amd_wdt_driver); + if (err) + return err; + + amd_wdt_platform_device = platform_device_register_simple( + WDT_MODULE_NAME, -1, NULL, 0); + if (IS_ERR(amd_wdt_platform_device)) { + err = PTR_ERR(amd_wdt_platform_device); + goto unreg_platform_driver; + } + + return 0; + +unreg_platform_driver: + platform_driver_unregister(&amd_wdt_driver); + return err; +} + +static void __exit amd_wdt_cleanup_module(void) +{ + platform_device_unregister(amd_wdt_platform_device); + platform_driver_unregister(&amd_wdt_driver); + pr_info("AMD Watchdog Module Unloaded\n"); +} + +module_init(amd_wdt_init_module); +module_exit(amd_wdt_cleanup_module); + +MODULE_AUTHOR("Arindam Nath <arindam.nath@amd.com>"); +MODULE_DESCRIPTION("Watchdog timer driver for AMD chipsets"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/meta-steppeeagle/recipes-kernel/amd-wdt/files/amd_wdt.h b/meta-steppeeagle/recipes-kernel/amd-wdt/files/amd_wdt.h new file mode 100644 index 00000000..116f370a --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/amd-wdt/files/amd_wdt.h @@ -0,0 +1,49 @@ +#ifndef _AMD_WDT_H_ +#define _AMD_WDT_H_ + +/* Module and version information */ +#define WDT_VERSION "0.1" +#define WDT_MODULE_NAME "AMD watchdog timer" +#define WDT_DRIVER_NAME WDT_MODULE_NAME ", v" WDT_VERSION + +#define WATCHDOG_HEARTBEAT 60 /* 60 units default heartbeat. */ +#define MAX_LENGTH (8 + 1) /* shutdown has 8 characters + NULL character */ + +/* Watchdog register definitions */ +#define AMD_ACPI_MMIO_BASE 0xFED80000 +#define AMD_WDT_MEM_MAP_OFFSET 0xB00 +#define AMD_WDT_MEM_MAP_SIZE 0x100 + +#define AMD_WDT_CONTROL(base) ((base) + 0x00) /* Watchdog Control */ + #define AMD_WDT_START_STOP_BIT (1 << 0) + #define AMD_WDT_FIRED_BIT (1 << 1) + #define AMD_WDT_ACTION_RESET_BIT (1 << 2) + #define AMD_WDT_DISABLE_BIT (1 << 3) + /* 6:4 bits Reserved */ + #define AMD_WDT_TRIGGER_BIT (1 << 7) +#define AMD_WDT_COUNT(base) ((base) + 0x04) /* Watchdog Count */ + #define AMD_WDT_COUNT_MASK 0xFFFF + +#define AMD_PM_WATCHDOG_EN_REG 0x00 + #define AMD_PM_WATCHDOG_TIMER_EN (0x01 << 7) + +#define AMD_PM_WATCHDOG_CONFIG_REG 0x03 + #define AMD_PM_WATCHDOG_32USEC_RES 0x0 + #define AMD_PM_WATCHDOG_10MSEC_RES 0x1 + #define AMD_PM_WATCHDOG_100MSEC_RES 0x2 + #define AMD_PM_WATCHDOG_1SEC_RES 0x3 +#define AMD_PM_WATCHDOG_CONFIG_MASK 0x3 + +/* IO port address for indirect access using ACPI PM registers */ +#define AMD_IO_PM_INDEX_REG 0xCD6 +#define AMD_IO_PM_DATA_REG 0xCD7 + +#define AMD_ACPI_MMIO_ADDR_MASK ~0x1FFF + +/* Watchdog device status */ +#define AMD_WDOG_ACTIVE 0 /* Is the watchdog running/active */ +#define AMD_WDOG_DEV_OPEN 1 /* Opended via /dev/watchdog */ +#define AMD_WDOG_ALLOW_RELEASE 2 /* Did we receive the magic char? */ +#define AMD_WDOG_NO_WAY_OUT 3 /* Is 'nowayout' feature set? */ + +#endif /* _AMD_WDT_H_ */ diff --git a/meta-steppeeagle/recipes-kernel/gpio-load/amd-gpio-load_1.0.bb b/meta-steppeeagle/recipes-kernel/gpio-load/amd-gpio-load_1.0.bb new file mode 100644 index 00000000..eba925e4 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/gpio-load/amd-gpio-load_1.0.bb @@ -0,0 +1,17 @@ +DESCRIPTION = "Configuration file to pass module load parameters to AMD GPIO driver" +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" + +SRC_URI = "file://modprobe.d/gpio-amd.conf" + +PR = "r0" +PV = "1.0" + +S = "${WORKDIR}" + +do_install() { + install -d ${D}/${sysconfdir}/modprobe.d/ + install -m 0644 modprobe.d/gpio-amd.conf ${D}${sysconfdir}/modprobe.d/ +} + +FILES_${PN} = "${sysconfdir}/modprobe.d" diff --git a/meta-steppeeagle/recipes-kernel/gpio-load/files/modprobe.d/gpio-amd.conf b/meta-steppeeagle/recipes-kernel/gpio-load/files/modprobe.d/gpio-amd.conf new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/gpio-load/files/modprobe.d/gpio-amd.conf diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware.bb b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware.bb new file mode 100644 index 00000000..e0e0999d --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware.bb @@ -0,0 +1,26 @@ +DESCRIPTION = "These binaries provide kernel support for AMD radeon GPUs" +SECTION = "kernel" +LICENSE = "Proprietary" + +FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" + +SRC_URI = "file://*.bin" + +LIC_FILES_CHKSUM = "file://LICENSE.radeon;md5=07b0c31777bd686d8e1609c6940b5e74" + +S = "${WORKDIR}" + +# Since, no binaries are generated for a specific target, +# inherit allarch to simply populate prebuilt binaries +inherit allarch + +do_compile() { + : +} + +do_install() { + install -v -m 444 -D ${S}/LICENSE.radeon ${D}/lib/firmware/radeon/LICENSE.radeon + install -v -m 0644 ${S}/*.bin ${D}/lib/firmware/radeon/ +} + +FILES_${PN} = "/lib/firmware/*" diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_ce.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_ce.bin Binary files differnew file mode 100644 index 00000000..7d40fbf1 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_ce.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_mc.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_mc.bin Binary files differnew file mode 100644 index 00000000..a3c70472 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_mc.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_me.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_me.bin Binary files differnew file mode 100644 index 00000000..75bff897 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_me.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_mec.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_mec.bin Binary files differnew file mode 100644 index 00000000..65fd6fb8 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_mec.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_pfp.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_pfp.bin Binary files differnew file mode 100644 index 00000000..e12a1af2 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_pfp.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_rlc.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_rlc.bin Binary files differnew file mode 100644 index 00000000..7e322354 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_rlc.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_sdma.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_sdma.bin Binary files differnew file mode 100644 index 00000000..4766a2a9 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_sdma.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_smc.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_smc.bin Binary files differnew file mode 100644 index 00000000..c735c6f4 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_smc.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_uvd.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_uvd.bin Binary files differnew file mode 100644 index 00000000..0876de9e --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_uvd.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_vce.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_vce.bin Binary files differnew file mode 100644 index 00000000..2fcf2696 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/BONAIRE_vce.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_ce.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_ce.bin Binary files differnew file mode 100644 index 00000000..497e1321 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_ce.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_mc.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_mc.bin Binary files differnew file mode 100644 index 00000000..a7b80c3d --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_mc.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_me.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_me.bin Binary files differnew file mode 100644 index 00000000..6dc895ba --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_me.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_pfp.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_pfp.bin Binary files differnew file mode 100644 index 00000000..1918d64a --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_pfp.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_rlc.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_rlc.bin Binary files differnew file mode 100644 index 00000000..df07678f --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_rlc.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_smc.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_smc.bin Binary files differnew file mode 100644 index 00000000..6bf5b369 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_smc.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_vce.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_vce.bin Binary files differnew file mode 100644 index 00000000..2fcf2696 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/HAINAN_vce.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_ce.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_ce.bin Binary files differnew file mode 100644 index 00000000..06d92de4 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_ce.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_me.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_me.bin Binary files differnew file mode 100644 index 00000000..543dc671 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_me.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_mec.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_mec.bin Binary files differnew file mode 100644 index 00000000..002ac5c0 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_mec.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_pfp.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_pfp.bin Binary files differnew file mode 100644 index 00000000..77590a14 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_pfp.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_rlc.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_rlc.bin Binary files differnew file mode 100644 index 00000000..ba84d86b --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_rlc.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_sdma.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_sdma.bin Binary files differnew file mode 100644 index 00000000..4766a2a9 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/KAVERI_sdma.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/LICENSE.radeon b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/LICENSE.radeon new file mode 100644 index 00000000..fe3780b3 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/LICENSE.radeon @@ -0,0 +1,51 @@ +Copyright (C) 2009-2014 Advanced Micro Devices, Inc. All rights reserved. + +REDISTRIBUTION: Permission is hereby granted, free of any license fees, +to any person obtaining a copy of this microcode (the "Software"), to +install, reproduce, copy and distribute copies, in binary form only, of +the Software and to permit persons to whom the Software is provided to +do the same, provided that the following conditions are met: + +No reverse engineering, decompilation, or disassembly of this Software +is permitted. + +Redistributions must reproduce the above copyright notice, this +permission notice, and the following disclaimers and notices in the +Software documentation and/or other materials provided with the +Software. + +DISCLAIMER: THE USE OF THE SOFTWARE IS AT YOUR SOLE RISK. THE SOFTWARE +IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND AND COPYRIGHT +HOLDER AND ITS LICENSORS EXPRESSLY DISCLAIM ALL WARRANTIES, EXPRESS AND +IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +COPYRIGHT HOLDER AND ITS LICENSORS DO NOT WARRANT THAT THE SOFTWARE WILL +MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF THE SOFTWARE WILL BE +UNINTERRUPTED OR ERROR-FREE. THE ENTIRE RISK ASSOCIATED WITH THE USE OF +THE SOFTWARE IS ASSUMED BY YOU. FURTHERMORE, COPYRIGHT HOLDER AND ITS +LICENSORS DO NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE +OR THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, +ACCURACY, RELIABILITY, CURRENTNESS, OR OTHERWISE. + +DISCLAIMER: UNDER NO CIRCUMSTANCES INCLUDING NEGLIGENCE, SHALL COPYRIGHT +HOLDER AND ITS LICENSORS OR ITS DIRECTORS, OFFICERS, EMPLOYEES OR AGENTS +("AUTHORIZED REPRESENTATIVES") BE LIABLE FOR ANY INCIDENTAL, INDIRECT, +SPECIAL OR CONSEQUENTIAL DAMAGES (INCLUDING DAMAGES FOR LOSS OF BUSINESS +PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, AND THE +LIKE) ARISING OUT OF THE USE, MISUSE OR INABILITY TO USE THE SOFTWARE, +BREACH OR DEFAULT, INCLUDING THOSE ARISING FROM INFRINGEMENT OR ALLEGED +INFRINGEMENT OF ANY PATENT, TRADEMARK, COPYRIGHT OR OTHER INTELLECTUAL +PROPERTY RIGHT EVEN IF COPYRIGHT HOLDER AND ITS AUTHORIZED +REPRESENTATIVES HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN +NO EVENT SHALL COPYRIGHT HOLDER OR ITS AUTHORIZED REPRESENTATIVES TOTAL +LIABILITY FOR ALL DAMAGES, LOSSES, AND CAUSES OF ACTION (WHETHER IN +CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE) EXCEED THE AMOUNT OF +US$10. + +Notice: The Software is subject to United States export laws and +regulations. You agree to comply with all domestic and international +export laws and regulations that apply to the Software, including but +not limited to the Export Administration Regulations administered by the +U.S. Department of Commerce and International Traffic in Arm Regulations +administered by the U.S. Department of State. These laws include +restrictions on destinations, end users and end use. diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_ce.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_ce.bin Binary files differnew file mode 100644 index 00000000..06d92de4 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_ce.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_me.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_me.bin Binary files differnew file mode 100644 index 00000000..543dc671 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_me.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_mec.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_mec.bin Binary files differnew file mode 100644 index 00000000..5ae6b387 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_mec.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_pfp.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_pfp.bin Binary files differnew file mode 100644 index 00000000..abe62fbc --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_pfp.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_rlc.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_rlc.bin Binary files differnew file mode 100644 index 00000000..8c24a03b --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_rlc.bin diff --git a/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_sdma.bin b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_sdma.bin Binary files differnew file mode 100644 index 00000000..4766a2a9 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux-firmware/radeon-firmware/MULLINS_sdma.bin diff --git a/meta-steppeeagle/recipes-kernel/linux/files/steppeeagle-user-features.scc b/meta-steppeeagle/recipes-kernel/linux/files/steppeeagle-user-features.scc new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/files/steppeeagle-user-features.scc diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch new file mode 100644 index 00000000..8540cbf0 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch @@ -0,0 +1,780 @@ +This single patch is a backport from kernel version 3.12.10 to kernel version +3.12. This lays the ground for the next set of patches which had been created +on top of 3.12.10. + +Signed-off-by: Arindam Nath <arindam.nath@amd.com> +diff -Naur a/drivers/acpi/bus.c b/drivers/acpi/bus.c +--- a/drivers/acpi/bus.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/acpi/bus.c 2014-04-03 02:38:06.049166833 +0530 +@@ -156,6 +156,16 @@ + } + EXPORT_SYMBOL(acpi_bus_get_private_data); + ++void acpi_bus_no_hotplug(acpi_handle handle) ++{ ++ struct acpi_device *adev = NULL; ++ ++ acpi_bus_get_device(handle, &adev); ++ if (adev) ++ adev->flags.no_hotplug = true; ++} ++EXPORT_SYMBOL_GPL(acpi_bus_no_hotplug); ++ + static void acpi_print_osc_error(acpi_handle handle, + struct acpi_osc_context *context, char *error) + { +diff -Naur a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c +--- a/drivers/gpu/drm/radeon/atombios_crtc.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c 2014-04-03 01:45:50.161111970 +0530 +@@ -1180,23 +1180,18 @@ + fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); + + if (rdev->family >= CHIP_BONAIRE) { +- u32 num_pipe_configs = rdev->config.cik.max_tile_pipes; +- u32 num_rb = rdev->config.cik.max_backends_per_se; +- if (num_pipe_configs > 8) +- num_pipe_configs = 8; +- if (num_pipe_configs == 8) +- fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P8_32x32_16x16); +- else if (num_pipe_configs == 4) { +- if (num_rb == 4) +- fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_16x16); +- else if (num_rb < 4) +- fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_8x16); +- } else if (num_pipe_configs == 2) +- fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P2); ++ /* Read the pipe config from the 2D TILED SCANOUT mode. ++ * It should be the same for the other modes too, but not all ++ * modes set the pipe config field. */ ++ u32 pipe_config = (rdev->config.cik.tile_mode_array[10] >> 6) & 0x1f; ++ ++ fb_format |= CIK_GRPH_PIPE_CONFIG(pipe_config); + } else if ((rdev->family == CHIP_TAHITI) || + (rdev->family == CHIP_PITCAIRN)) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); +- else if (rdev->family == CHIP_VERDE) ++ else if ((rdev->family == CHIP_VERDE) || ++ (rdev->family == CHIP_OLAND) || ++ (rdev->family == CHIP_HAINAN)) /* for completeness. HAINAN has no display hw */ + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); + + switch (radeon_crtc->crtc_id) { +@@ -1753,7 +1748,7 @@ + if (pll != ATOM_PPLL_INVALID) + return pll; + } +- } else { ++ } else if (!ASIC_IS_DCE41(rdev)) { /* Don't share PLLs on DCE4.1 chips */ + /* use the same PPLL for all monitors with the same clock */ + pll = radeon_get_shared_nondp_ppll(crtc); + if (pll != ATOM_PPLL_INVALID) +diff -Naur a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c +--- a/drivers/gpu/drm/radeon/atombios_i2c.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/atombios_i2c.c 2014-04-03 01:45:50.161111970 +0530 +@@ -44,7 +44,7 @@ + PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; + int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); + unsigned char *base; +- u16 out; ++ u16 out = cpu_to_le16(0); + + memset(&args, 0, sizeof(args)); + +@@ -55,9 +55,14 @@ + DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 3)\n", num); + return -EINVAL; + } +- args.ucRegIndex = buf[0]; +- if (num > 1) +- memcpy(&out, &buf[1], num - 1); ++ if (buf == NULL) ++ args.ucRegIndex = 0; ++ else ++ args.ucRegIndex = buf[0]; ++ if (num) ++ num--; ++ if (num) ++ memcpy(&out, &buf[1], num); + args.lpI2CDataOut = cpu_to_le16(out); + } else { + if (num > ATOM_MAX_HW_I2C_READ) { +@@ -94,14 +99,14 @@ + struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); + struct i2c_msg *p; + int i, remaining, current_count, buffer_offset, max_bytes, ret; +- u8 buf = 0, flags; ++ u8 flags; + + /* check for bus probe */ + p = &msgs[0]; + if ((num == 1) && (p->len == 0)) { + ret = radeon_process_i2c_ch(i2c, + p->addr, HW_I2C_WRITE, +- &buf, 1); ++ NULL, 0); + if (ret) + return ret; + else +diff -Naur a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +--- a/drivers/gpu/drm/radeon/cik.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/cik.c 2014-04-03 01:45:50.165111971 +0530 +@@ -2608,7 +2608,7 @@ + * Returns the disabled RB bitmask. + */ + static u32 cik_get_rb_disabled(struct radeon_device *rdev, +- u32 max_rb_num, u32 se_num, ++ u32 max_rb_num_per_se, + u32 sh_per_se) + { + u32 data, mask; +@@ -2622,7 +2622,7 @@ + + data >>= BACKEND_DISABLE_SHIFT; + +- mask = cik_create_bitmask(max_rb_num / se_num / sh_per_se); ++ mask = cik_create_bitmask(max_rb_num_per_se / sh_per_se); + + return data & mask; + } +@@ -2639,7 +2639,7 @@ + */ + static void cik_setup_rb(struct radeon_device *rdev, + u32 se_num, u32 sh_per_se, +- u32 max_rb_num) ++ u32 max_rb_num_per_se) + { + int i, j; + u32 data, mask; +@@ -2649,19 +2649,21 @@ + for (i = 0; i < se_num; i++) { + for (j = 0; j < sh_per_se; j++) { + cik_select_se_sh(rdev, i, j); +- data = cik_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se); ++ data = cik_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se); + disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH); + } + } + cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); + + mask = 1; +- for (i = 0; i < max_rb_num; i++) { ++ for (i = 0; i < max_rb_num_per_se * se_num; i++) { + if (!(disabled_rbs & mask)) + enabled_rbs |= mask; + mask <<= 1; + } + ++ rdev->config.cik.backend_enable_mask = enabled_rbs; ++ + for (i = 0; i < se_num; i++) { + cik_select_se_sh(rdev, i, 0xffffffff); + data = 0; +diff -Naur a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c +--- a/drivers/gpu/drm/radeon/cik_sdma.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/cik_sdma.c 2014-04-03 01:45:50.169111972 +0530 +@@ -468,7 +468,7 @@ + radeon_ring_write(ring, 0); /* src/dst endian swap */ + radeon_ring_write(ring, src_offset & 0xffffffff); + radeon_ring_write(ring, upper_32_bits(src_offset) & 0xffffffff); +- radeon_ring_write(ring, dst_offset & 0xfffffffc); ++ radeon_ring_write(ring, dst_offset & 0xffffffff); + radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xffffffff); + src_offset += cur_size_in_bytes; + dst_offset += cur_size_in_bytes; +diff -Naur a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c +--- a/drivers/gpu/drm/radeon/dce6_afmt.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/dce6_afmt.c 2014-04-03 01:45:50.169111972 +0530 +@@ -132,7 +132,7 @@ + } + + sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); +- if (sad_count < 0) { ++ if (sad_count <= 0) { + DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); + return; + } +@@ -193,7 +193,7 @@ + } + + sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); +- if (sad_count < 0) { ++ if (sad_count <= 0) { + DRM_ERROR("Couldn't read SADs: %d\n", sad_count); + return; + } +diff -Naur a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c +--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c 2014-04-03 01:45:50.169111972 +0530 +@@ -81,7 +81,7 @@ + } + + sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); +- if (sad_count < 0) { ++ if (sad_count <= 0) { + DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); + return; + } +@@ -134,7 +134,7 @@ + } + + sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); +- if (sad_count < 0) { ++ if (sad_count <= 0) { + DRM_ERROR("Couldn't read SADs: %d\n", sad_count); + return; + } +diff -Naur a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +--- a/drivers/gpu/drm/radeon/ni.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/ni.c 2014-04-03 01:45:50.169111972 +0530 +@@ -900,6 +900,10 @@ + (rdev->pdev->device == 0x999C)) { + rdev->config.cayman.max_simds_per_se = 6; + rdev->config.cayman.max_backends_per_se = 2; ++ rdev->config.cayman.max_hw_contexts = 8; ++ rdev->config.cayman.sx_max_export_size = 256; ++ rdev->config.cayman.sx_max_export_pos_size = 64; ++ rdev->config.cayman.sx_max_export_smx_size = 192; + } else if ((rdev->pdev->device == 0x9903) || + (rdev->pdev->device == 0x9904) || + (rdev->pdev->device == 0x990A) || +@@ -910,6 +914,10 @@ + (rdev->pdev->device == 0x999D)) { + rdev->config.cayman.max_simds_per_se = 4; + rdev->config.cayman.max_backends_per_se = 2; ++ rdev->config.cayman.max_hw_contexts = 8; ++ rdev->config.cayman.sx_max_export_size = 256; ++ rdev->config.cayman.sx_max_export_pos_size = 64; ++ rdev->config.cayman.sx_max_export_smx_size = 192; + } else if ((rdev->pdev->device == 0x9919) || + (rdev->pdev->device == 0x9990) || + (rdev->pdev->device == 0x9991) || +@@ -920,9 +928,17 @@ + (rdev->pdev->device == 0x99A0)) { + rdev->config.cayman.max_simds_per_se = 3; + rdev->config.cayman.max_backends_per_se = 1; ++ rdev->config.cayman.max_hw_contexts = 4; ++ rdev->config.cayman.sx_max_export_size = 128; ++ rdev->config.cayman.sx_max_export_pos_size = 32; ++ rdev->config.cayman.sx_max_export_smx_size = 96; + } else { + rdev->config.cayman.max_simds_per_se = 2; + rdev->config.cayman.max_backends_per_se = 1; ++ rdev->config.cayman.max_hw_contexts = 4; ++ rdev->config.cayman.sx_max_export_size = 128; ++ rdev->config.cayman.sx_max_export_pos_size = 32; ++ rdev->config.cayman.sx_max_export_smx_size = 96; + } + rdev->config.cayman.max_texture_channel_caches = 2; + rdev->config.cayman.max_gprs = 256; +@@ -930,10 +946,6 @@ + rdev->config.cayman.max_gs_threads = 32; + rdev->config.cayman.max_stack_entries = 512; + rdev->config.cayman.sx_num_of_sets = 8; +- rdev->config.cayman.sx_max_export_size = 256; +- rdev->config.cayman.sx_max_export_pos_size = 64; +- rdev->config.cayman.sx_max_export_smx_size = 192; +- rdev->config.cayman.max_hw_contexts = 8; + rdev->config.cayman.sq_num_cf_insts = 2; + + rdev->config.cayman.sc_prim_fifo_size = 0x40; +diff -Naur a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c +--- a/drivers/gpu/drm/radeon/r600_hdmi.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/r600_hdmi.c 2014-04-03 01:45:50.169111972 +0530 +@@ -24,6 +24,7 @@ + * Authors: Christian König + */ + #include <linux/hdmi.h> ++#include <linux/gcd.h> + #include <drm/drmP.h> + #include <drm/radeon_drm.h> + #include "radeon.h" +@@ -57,35 +58,57 @@ + static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { + /* 32kHz 44.1kHz 48kHz */ + /* Clock N CTS N CTS N CTS */ +- { 25175, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */ ++ { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */ + { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ + { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ + { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ + { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ + { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ +- { 74176, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */ ++ { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */ + { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ +- { 148352, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */ ++ { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */ + { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ +- { 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */ + }; + ++ + /* +- * calculate CTS value if it's not found in the table ++ * calculate CTS and N values if they are not found in the table + */ +-static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq) ++static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) + { +- u64 n; +- u32 d; ++ int n, cts; ++ unsigned long div, mul; + +- if (*CTS == 0) { +- n = (u64)clock * (u64)N * 1000ULL; +- d = 128 * freq; +- do_div(n, d); +- *CTS = n; +- } +- DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n", +- N, *CTS, freq); ++ /* Safe, but overly large values */ ++ n = 128 * freq; ++ cts = clock * 1000; ++ ++ /* Smallest valid fraction */ ++ div = gcd(n, cts); ++ ++ n /= div; ++ cts /= div; ++ ++ /* ++ * The optimal N is 128*freq/1000. Calculate the closest larger ++ * value that doesn't truncate any bits. ++ */ ++ mul = ((128*freq/1000) + (n-1))/n; ++ ++ n *= mul; ++ cts *= mul; ++ ++ /* Check that we are in spec (not always possible) */ ++ if (n < (128*freq/1500)) ++ printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n"); ++ if (n > (128*freq/300)) ++ printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n"); ++ ++ *N = n; ++ *CTS = cts; ++ ++ DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n", ++ *N, *CTS, freq); + } + + struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock) +@@ -93,15 +116,16 @@ + struct radeon_hdmi_acr res; + u8 i; + +- for (i = 0; r600_hdmi_predefined_acr[i].clock != clock && +- r600_hdmi_predefined_acr[i].clock != 0; i++) +- ; +- res = r600_hdmi_predefined_acr[i]; +- +- /* In case some CTS are missing */ +- r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000); +- r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100); +- r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000); ++ /* Precalculated values for common clocks */ ++ for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) { ++ if (r600_hdmi_predefined_acr[i].clock == clock) ++ return r600_hdmi_predefined_acr[i]; ++ } ++ ++ /* And odd clocks get manually calculated */ ++ r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); ++ r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); ++ r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); + + return res; + } +@@ -280,9 +304,9 @@ + WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo); + WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ + } +- } else if (ASIC_IS_DCE3(rdev)) { ++ } else { + /* according to the reg specs, this should DCE3.2 only, but in +- * practice it seems to cover DCE3.0/3.1 as well. ++ * practice it seems to cover DCE2.0/3.0/3.1 as well. + */ + if (dig->dig_encoder == 0) { + WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); +@@ -293,10 +317,6 @@ + WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); + WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ + } +- } else { +- /* according to the reg specs, this should be DCE2.0 and DCE3.0/3.1 */ +- WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | +- AUDIO_DTO_MODULE(clock / 10)); + } + } + +diff -Naur a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c +--- a/drivers/gpu/drm/radeon/radeon_asic.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_asic.c 2014-04-03 01:45:50.173111972 +0530 +@@ -2019,6 +2019,8 @@ + .bandwidth_update = &dce8_bandwidth_update, + .get_vblank_counter = &evergreen_get_vblank_counter, + .wait_for_vblank = &dce4_wait_for_vblank, ++ .set_backlight_level = &atombios_set_backlight_level, ++ .get_backlight_level = &atombios_get_backlight_level, + .hdmi_enable = &evergreen_hdmi_enable, + .hdmi_setmode = &evergreen_hdmi_setmode, + }, +@@ -2119,6 +2121,8 @@ + .bandwidth_update = &dce8_bandwidth_update, + .get_vblank_counter = &evergreen_get_vblank_counter, + .wait_for_vblank = &dce4_wait_for_vblank, ++ .set_backlight_level = &atombios_set_backlight_level, ++ .get_backlight_level = &atombios_get_backlight_level, + .hdmi_enable = &evergreen_hdmi_enable, + .hdmi_setmode = &evergreen_hdmi_setmode, + }, +diff -Naur a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c +--- a/drivers/gpu/drm/radeon/radeon_atombios.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c 2014-04-03 01:45:50.173111972 +0530 +@@ -2918,7 +2918,7 @@ + mpll_param->dll_speed = args.ucDllSpeed; + mpll_param->bwcntl = args.ucBWCntl; + mpll_param->vco_mode = +- (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK) ? 1 : 0; ++ (args.ucPllCntlFlag & MPLL_CNTL_FLAG_VCO_MODE_MASK); + mpll_param->yclk_sel = + (args.ucPllCntlFlag & MPLL_CNTL_FLAG_BYPASS_DQ_PLL) ? 1 : 0; + mpll_param->qdr = +diff -Naur a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c +--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c 2014-04-03 01:45:50.173111972 +0530 +@@ -34,6 +34,7 @@ + bool atpx_detected; + /* handle for device - and atpx */ + acpi_handle dhandle; ++ acpi_handle other_handle; + struct radeon_atpx atpx; + } radeon_atpx_priv; + +@@ -448,9 +449,10 @@ + return false; + + status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); +- if (ACPI_FAILURE(status)) ++ if (ACPI_FAILURE(status)) { ++ radeon_atpx_priv.other_handle = dhandle; + return false; +- ++ } + radeon_atpx_priv.dhandle = dhandle; + radeon_atpx_priv.atpx.handle = atpx_handle; + return true; +@@ -527,6 +529,16 @@ + printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", + acpi_method_name); + radeon_atpx_priv.atpx_detected = true; ++ /* ++ * On some systems hotplug events are generated for the device ++ * being switched off when ATPX is executed. They cause ACPI ++ * hotplug to trigger and attempt to remove the device from ++ * the system, which causes it to break down. Prevent that from ++ * happening by setting the no_hotplug flag for the involved ++ * ACPI device objects. ++ */ ++ acpi_bus_no_hotplug(radeon_atpx_priv.dhandle); ++ acpi_bus_no_hotplug(radeon_atpx_priv.other_handle); + return true; + } + return false; +diff -Naur a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c +--- a/drivers/gpu/drm/radeon/radeon_gart.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_gart.c 2014-04-03 01:45:50.173111972 +0530 +@@ -1156,6 +1156,8 @@ + return -ENOMEM; + + r = radeon_ib_get(rdev, ridx, &ib, NULL, ndw * 4); ++ if (r) ++ return r; + ib.length_dw = 0; + + r = radeon_vm_update_pdes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset); +diff -Naur a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +--- a/drivers/gpu/drm/radeon/radeon.h 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon.h 2014-04-03 01:45:50.177111972 +0530 +@@ -1930,7 +1930,7 @@ + unsigned sc_earlyz_tile_fifo_size; + + unsigned num_tile_pipes; +- unsigned num_backends_per_se; ++ unsigned backend_enable_mask; + unsigned backend_disable_mask_per_asic; + unsigned backend_map; + unsigned num_texture_channel_caches; +@@ -1960,7 +1960,7 @@ + unsigned sc_earlyz_tile_fifo_size; + + unsigned num_tile_pipes; +- unsigned num_backends_per_se; ++ unsigned backend_enable_mask; + unsigned backend_disable_mask_per_asic; + unsigned backend_map; + unsigned num_texture_channel_caches; +diff -Naur a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +--- a/drivers/gpu/drm/radeon/radeon_kms.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_kms.c 2014-04-03 01:45:50.177111972 +0530 +@@ -436,6 +436,15 @@ + case RADEON_INFO_SI_CP_DMA_COMPUTE: + *value = 1; + break; ++ case RADEON_INFO_SI_BACKEND_ENABLED_MASK: ++ if (rdev->family >= CHIP_BONAIRE) { ++ *value = rdev->config.cik.backend_enable_mask; ++ } else if (rdev->family >= CHIP_TAHITI) { ++ *value = rdev->config.si.backend_enable_mask; ++ } else { ++ DRM_DEBUG_KMS("BACKEND_ENABLED_MASK is si+ only!\n"); ++ } ++ break; + default: + DRM_DEBUG_KMS("Invalid request %d\n", info->request); + return -EINVAL; +diff -Naur a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c 2014-04-03 01:45:50.181111972 +0530 +@@ -422,6 +422,7 @@ + /* Pin framebuffer & get tilling informations */ + obj = radeon_fb->obj; + rbo = gem_to_radeon_bo(obj); ++retry: + r = radeon_bo_reserve(rbo, false); + if (unlikely(r != 0)) + return r; +@@ -430,6 +431,33 @@ + &base); + if (unlikely(r != 0)) { + radeon_bo_unreserve(rbo); ++ ++ /* On old GPU like RN50 with little vram pining can fails because ++ * current fb is taking all space needed. So instead of unpining ++ * the old buffer after pining the new one, first unpin old one ++ * and then retry pining new one. ++ * ++ * As only master can set mode only master can pin and it is ++ * unlikely the master client will race with itself especialy ++ * on those old gpu with single crtc. ++ * ++ * We don't shutdown the display controller because new buffer ++ * will end up in same spot. ++ */ ++ if (!atomic && fb && fb != crtc->fb) { ++ struct radeon_bo *old_rbo; ++ unsigned long nsize, osize; ++ ++ old_rbo = gem_to_radeon_bo(to_radeon_framebuffer(fb)->obj); ++ osize = radeon_bo_size(old_rbo); ++ nsize = radeon_bo_size(rbo); ++ if (nsize <= osize && !radeon_bo_reserve(old_rbo, false)) { ++ radeon_bo_unpin(old_rbo); ++ radeon_bo_unreserve(old_rbo); ++ fb = NULL; ++ goto retry; ++ } ++ } + return -EINVAL; + } + radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); +diff -Naur a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c +--- a/drivers/gpu/drm/radeon/radeon_uvd.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_uvd.c 2014-04-03 01:45:50.181111972 +0530 +@@ -240,6 +240,8 @@ + if (handle != 0 && rdev->uvd.filp[i] == filp) { + struct radeon_fence *fence; + ++ radeon_uvd_note_usage(rdev); ++ + r = radeon_uvd_get_destroy_msg(rdev, + R600_RING_TYPE_UVD_INDEX, handle, &fence); + if (r) { +@@ -470,7 +472,7 @@ + return -EINVAL; + } + +- if ((start >> 28) != (end >> 28)) { ++ if ((start >> 28) != ((end - 1) >> 28)) { + DRM_ERROR("reloc %LX-%LX crossing 256MB boundary!\n", + start, end); + return -EINVAL; +@@ -620,7 +622,7 @@ + if (r) + goto err; + +- r = radeon_ib_get(rdev, ring, &ib, NULL, 16); ++ r = radeon_ib_get(rdev, ring, &ib, NULL, 64); + if (r) + goto err; + +diff -Naur a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c +--- a/drivers/gpu/drm/radeon/rs690.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/rs690.c 2014-04-03 01:45:50.181111972 +0530 +@@ -162,6 +162,16 @@ + base = RREG32_MC(R_000100_MCCFG_FB_LOCATION); + base = G_000100_MC_FB_START(base) << 16; + rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); ++ /* Some boards seem to be configured for 128MB of sideport memory, ++ * but really only have 64MB. Just skip the sideport and use ++ * UMA memory. ++ */ ++ if (rdev->mc.igp_sideport_enabled && ++ (rdev->mc.real_vram_size == (384 * 1024 * 1024))) { ++ base += 128 * 1024 * 1024; ++ rdev->mc.real_vram_size -= 128 * 1024 * 1024; ++ rdev->mc.mc_vram_size = rdev->mc.real_vram_size; ++ } + + /* Use K8 direct mapping for fast fb access. */ + rdev->fastfb_working = false; +diff -Naur a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c +--- a/drivers/gpu/drm/radeon/rv770_dpm.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/rv770_dpm.c 2014-04-03 01:45:50.185111972 +0530 +@@ -2328,6 +2328,12 @@ + pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss, + ASIC_INTERNAL_MEMORY_SS, 0); + ++ /* disable ss, causes hangs on some cayman boards */ ++ if (rdev->family == CHIP_CAYMAN) { ++ pi->sclk_ss = false; ++ pi->mclk_ss = false; ++ } ++ + if (pi->sclk_ss || pi->mclk_ss) + pi->dynamic_ss = true; + else +diff -Naur a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +--- a/drivers/gpu/drm/radeon/si.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/si.c 2014-04-03 01:45:50.189111972 +0530 +@@ -2816,7 +2816,7 @@ + } + + static u32 si_get_rb_disabled(struct radeon_device *rdev, +- u32 max_rb_num, u32 se_num, ++ u32 max_rb_num_per_se, + u32 sh_per_se) + { + u32 data, mask; +@@ -2830,14 +2830,14 @@ + + data >>= BACKEND_DISABLE_SHIFT; + +- mask = si_create_bitmask(max_rb_num / se_num / sh_per_se); ++ mask = si_create_bitmask(max_rb_num_per_se / sh_per_se); + + return data & mask; + } + + static void si_setup_rb(struct radeon_device *rdev, + u32 se_num, u32 sh_per_se, +- u32 max_rb_num) ++ u32 max_rb_num_per_se) + { + int i, j; + u32 data, mask; +@@ -2847,19 +2847,21 @@ + for (i = 0; i < se_num; i++) { + for (j = 0; j < sh_per_se; j++) { + si_select_se_sh(rdev, i, j); +- data = si_get_rb_disabled(rdev, max_rb_num, se_num, sh_per_se); ++ data = si_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se); + disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH); + } + } + si_select_se_sh(rdev, 0xffffffff, 0xffffffff); + + mask = 1; +- for (i = 0; i < max_rb_num; i++) { ++ for (i = 0; i < max_rb_num_per_se * se_num; i++) { + if (!(disabled_rbs & mask)) + enabled_rbs |= mask; + mask <<= 1; + } + ++ rdev->config.si.backend_enable_mask = enabled_rbs; ++ + for (i = 0; i < se_num; i++) { + si_select_se_sh(rdev, i, 0xffffffff); + data = 0; +@@ -3887,8 +3889,15 @@ + rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); + rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); + /* size in MB on si */ +- rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; +- rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; ++ tmp = RREG32(CONFIG_MEMSIZE); ++ /* some boards may have garbage in the upper 16 bits */ ++ if (tmp & 0xffff0000) { ++ DRM_INFO("Probable bad vram size: 0x%08x\n", tmp); ++ if (tmp & 0xffff) ++ tmp &= 0xffff; ++ } ++ rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL; ++ rdev->mc.real_vram_size = rdev->mc.mc_vram_size; + rdev->mc.visible_vram_size = rdev->mc.aper_size; + si_vram_gtt_location(rdev, &rdev->mc); + radeon_update_bandwidth_info(rdev); +diff -Naur a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h +--- a/drivers/gpu/drm/radeon/sid.h 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/sid.h 2014-04-03 01:45:50.189111972 +0530 +@@ -478,7 +478,7 @@ + #define STATE3_MASK (0x1f << 15) + #define STATE3_SHIFT 15 + +-#define MC_SEQ_TRAIN_WAKEUP_CNTL 0x2808 ++#define MC_SEQ_TRAIN_WAKEUP_CNTL 0x28e8 + #define TRAIN_DONE_D0 (1 << 30) + #define TRAIN_DONE_D1 (1 << 31) + +diff -Naur a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c +--- a/drivers/gpu/drm/radeon/trinity_dpm.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/trinity_dpm.c 2014-04-03 01:45:50.193111972 +0530 +@@ -1873,9 +1873,9 @@ + pi->enable_sclk_ds = true; + pi->enable_gfx_power_gating = true; + pi->enable_gfx_clock_gating = true; +- pi->enable_mg_clock_gating = true; +- pi->enable_gfx_dynamic_mgpg = true; /* ??? */ +- pi->override_dynamic_mgpg = true; ++ pi->enable_mg_clock_gating = false; ++ pi->enable_gfx_dynamic_mgpg = false; ++ pi->override_dynamic_mgpg = false; + pi->enable_auto_thermal_throttling = true; + pi->voltage_drop_in_dce = false; /* need to restructure dpm/modeset interaction */ + pi->uvd_dpm = true; /* ??? */ +diff -Naur a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h +--- a/include/acpi/acpi_bus.h 2013-11-04 05:11:51.000000000 +0530 ++++ b/include/acpi/acpi_bus.h 2014-04-03 02:41:15.381170177 +0530 +@@ -168,6 +168,7 @@ + u32 ejectable:1; + u32 power_manageable:1; + u32 match_driver:1; ++ u32 no_hotplug:1; + u32 reserved:27; + }; + +@@ -356,6 +357,7 @@ + extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); + void acpi_bus_private_data_handler(acpi_handle, void *); + int acpi_bus_get_private_data(acpi_handle, void **); ++void acpi_bus_no_hotplug(acpi_handle handle); + extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); + extern int register_acpi_notifier(struct notifier_block *); + extern int unregister_acpi_notifier(struct notifier_block *); +diff -Naur a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h +--- a/include/uapi/drm/radeon_drm.h 2013-11-04 05:11:51.000000000 +0530 ++++ b/include/uapi/drm/radeon_drm.h 2014-04-03 02:30:27.125158815 +0530 +@@ -981,6 +981,8 @@ + #define RADEON_INFO_SI_TILE_MODE_ARRAY 0x16 + /* query if CP DMA is supported on the compute ring */ + #define RADEON_INFO_SI_CP_DMA_COMPUTE 0x17 ++/* query the number of render backends */ ++#define RADEON_INFO_SI_BACKEND_ENABLED_MASK 0x19 + + + struct drm_radeon_info { diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0001-yocto-amd-drm-radeon-add-vm_set_page-tracepoint.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0001-yocto-amd-drm-radeon-add-vm_set_page-tracepoint.patch new file mode 100644 index 00000000..7374ddfe --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0001-yocto-amd-drm-radeon-add-vm_set_page-tracepoint.patch @@ -0,0 +1,118 @@ +From c97f6a9d11c7350c40e84ae85851e46f546e9ace Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Tue, 29 Oct 2013 20:14:48 +0100 +Subject: [PATCH 01/44] drm/radeon: add vm_set_page tracepoint +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/cik_sdma.c | 3 +++ + drivers/gpu/drm/radeon/ni_dma.c | 3 +++ + drivers/gpu/drm/radeon/radeon_trace.h | 24 ++++++++++++++++++++++++ + drivers/gpu/drm/radeon/si_dma.c | 3 +++ + 4 files changed, 33 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c +index aaf7ffc..ed65b6e 100644 +--- a/drivers/gpu/drm/radeon/cik_sdma.c ++++ b/drivers/gpu/drm/radeon/cik_sdma.c +@@ -25,6 +25,7 @@ + #include <drm/drmP.h> + #include "radeon.h" + #include "radeon_asic.h" ++#include "radeon_trace.h" + #include "cikd.h" + + /* sdma */ +@@ -657,6 +658,8 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, + uint64_t value; + unsigned ndw; + ++ trace_radeon_vm_set_page(pe, addr, count, incr, r600_flags); ++ + if (flags & RADEON_VM_PAGE_SYSTEM) { + while (count) { + ndw = count * 2; +diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c +index dd6e968..e9cfe8a 100644 +--- a/drivers/gpu/drm/radeon/ni_dma.c ++++ b/drivers/gpu/drm/radeon/ni_dma.c +@@ -24,6 +24,7 @@ + #include <drm/drmP.h> + #include "radeon.h" + #include "radeon_asic.h" ++#include "radeon_trace.h" + #include "nid.h" + + u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev); +@@ -260,6 +261,8 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, + uint64_t value; + unsigned ndw; + ++ trace_radeon_vm_set_page(pe, addr, count, incr, r600_flags); ++ + if ((flags & RADEON_VM_PAGE_SYSTEM) || (count == 1)) { + while (count) { + ndw = count * 2; +diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h +index f7e3678..811bca6 100644 +--- a/drivers/gpu/drm/radeon/radeon_trace.h ++++ b/drivers/gpu/drm/radeon/radeon_trace.h +@@ -47,6 +47,30 @@ TRACE_EVENT(radeon_cs, + __entry->fences) + ); + ++TRACE_EVENT(radeon_vm_set_page, ++ TP_PROTO(uint64_t pe, uint64_t addr, unsigned count, ++ uint32_t incr, uint32_t flags), ++ TP_ARGS(pe, addr, count, incr, flags), ++ TP_STRUCT__entry( ++ __field(u64, pe) ++ __field(u64, addr) ++ __field(u32, count) ++ __field(u32, incr) ++ __field(u32, flags) ++ ), ++ ++ TP_fast_assign( ++ __entry->pe = pe; ++ __entry->addr = addr; ++ __entry->count = count; ++ __entry->incr = incr; ++ __entry->flags = flags; ++ ), ++ TP_printk("pe=%010Lx, addr=%010Lx, incr=%u, flags=%08x, count=%u", ++ __entry->pe, __entry->addr, __entry->incr, ++ __entry->flags, __entry->count) ++); ++ + DECLARE_EVENT_CLASS(radeon_fence_request, + + TP_PROTO(struct drm_device *dev, u32 seqno), +diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c +index 49909d2..17205fd 100644 +--- a/drivers/gpu/drm/radeon/si_dma.c ++++ b/drivers/gpu/drm/radeon/si_dma.c +@@ -24,6 +24,7 @@ + #include <drm/drmP.h> + #include "radeon.h" + #include "radeon_asic.h" ++#include "radeon_trace.h" + #include "sid.h" + + u32 si_gpu_check_soft_reset(struct radeon_device *rdev); +@@ -79,6 +80,8 @@ void si_dma_vm_set_page(struct radeon_device *rdev, + uint64_t value; + unsigned ndw; + ++ trace_radeon_vm_set_page(pe, addr, count, incr, r600_flags); ++ + if (flags & RADEON_VM_PAGE_SYSTEM) { + while (count) { + ndw = count * 2; +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0002-yocto-amd-drm-radeon-cleanup-flushing-on-CIK-v3.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0002-yocto-amd-drm-radeon-cleanup-flushing-on-CIK-v3.patch new file mode 100644 index 00000000..986489c2 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0002-yocto-amd-drm-radeon-cleanup-flushing-on-CIK-v3.patch @@ -0,0 +1,96 @@ +From eee59eb01ab5dcbf99d6c11d5467f933e76ba99f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= <marek.olsak@amd.com> +Date: Sat, 19 Oct 2013 22:06:43 +0200 +Subject: [PATCH 02/44] drm/radeon: cleanup flushing on CIK (v3) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +v2: fix compute handling. +v3: use HDP_MEM_COHERENCY_FLUSH_CNTL again + +Signed-off-by: Marek Olšák <marek.olsak@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/cik.c | 43 +++++++++++++++--------------------------- + 1 file changed, 15 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index 31f5f0e..2277a59 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -3011,6 +3011,18 @@ int cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) + return r; + } + ++static void cik_cp_hdp_flush(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ /* Request an HDP flush */ ++ radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); ++ radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | ++ WRITE_DATA_DST_SEL(0))); ++ radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); ++ radeon_ring_write(ring, 0); ++ radeon_ring_write(ring, 0); ++} ++ + /** + * cik_fence_gfx_ring_emit - emit a fence on the gfx ring + * +@@ -3037,15 +3049,7 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev, + radeon_ring_write(ring, fence->seq); + radeon_ring_write(ring, 0); + /* HDP flush */ +- /* We should be using the new WAIT_REG_MEM special op packet here +- * but it causes the CP to hang +- */ +- radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); +- radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | +- WRITE_DATA_DST_SEL(0))); +- radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); +- radeon_ring_write(ring, 0); +- radeon_ring_write(ring, 0); ++ cik_cp_hdp_flush(rdev, ring); + } + + /** +@@ -3075,15 +3079,7 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev, + radeon_ring_write(ring, fence->seq); + radeon_ring_write(ring, 0); + /* HDP flush */ +- /* We should be using the new WAIT_REG_MEM special op packet here +- * but it causes the CP to hang +- */ +- radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); +- radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | +- WRITE_DATA_DST_SEL(0))); +- radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); +- radeon_ring_write(ring, 0); +- radeon_ring_write(ring, 0); ++ cik_cp_hdp_flush(rdev, ring); + } + + void cik_semaphore_ring_emit(struct radeon_device *rdev, +@@ -4809,16 +4805,7 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) + radeon_ring_write(ring, VMID(0)); + + /* HDP flush */ +- /* We should be using the WAIT_REG_MEM packet here like in +- * cik_fence_ring_emit(), but it causes the CP to hang in this +- * context... +- */ +- radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); +- radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | +- WRITE_DATA_DST_SEL(0))); +- radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); +- radeon_ring_write(ring, 0); +- radeon_ring_write(ring, 0); ++ cik_cp_hdp_flush(rdev, ring); + + /* bits 0-15 are the VM contexts0-15 */ + radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0003-yocto-amd-drm-radeon-cleanup-DMA-HDP-flush-on-CIK-v2.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0003-yocto-amd-drm-radeon-cleanup-DMA-HDP-flush-on-CIK-v2.patch new file mode 100644 index 00000000..8fe9e087 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0003-yocto-amd-drm-radeon-cleanup-DMA-HDP-flush-on-CIK-v2.patch @@ -0,0 +1,100 @@ +From 9c318cd900e41358c7507cb144f0ef8f5c0bbb19 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Tue, 5 Nov 2013 18:12:13 -0500 +Subject: [PATCH 03/44] drm/radeon: cleanup DMA HDP flush on CIK (v2) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +v2: use HDP_MEM_COHERENCY_FLUSH_CNTL again + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/cik_sdma.c | 38 ++++++++++--------------------------- + 1 file changed, 10 insertions(+), 28 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c +index ed65b6e..56ede52 100644 +--- a/drivers/gpu/drm/radeon/cik_sdma.c ++++ b/drivers/gpu/drm/radeon/cik_sdma.c +@@ -51,6 +51,14 @@ u32 cik_gpu_check_soft_reset(struct radeon_device *rdev); + * buffers. + */ + ++static void cik_sdma_hdp_flush(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); ++ radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); ++ radeon_ring_write(ring, 0x0); ++} ++ + /** + * cik_sdma_ring_ib_execute - Schedule an IB on the DMA engine + * +@@ -102,14 +110,6 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev, + { + struct radeon_ring *ring = &rdev->ring[fence->ring]; + u64 addr = rdev->fence_drv[fence->ring].gpu_addr; +- u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) | +- SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */ +- u32 ref_and_mask; +- +- if (fence->ring == R600_RING_TYPE_DMA_INDEX) +- ref_and_mask = SDMA0; +- else +- ref_and_mask = SDMA1; + + /* write the fence */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_FENCE, 0, 0)); +@@ -119,12 +119,7 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev, + /* generate an interrupt */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_TRAP, 0, 0)); + /* flush HDP */ +- radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); +- radeon_ring_write(ring, GPU_HDP_FLUSH_DONE); +- radeon_ring_write(ring, GPU_HDP_FLUSH_REQ); +- radeon_ring_write(ring, ref_and_mask); /* REFERENCE */ +- radeon_ring_write(ring, ref_and_mask); /* MASK */ +- radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */ ++ cik_sdma_hdp_flush(rdev, ring); + } + + /** +@@ -727,18 +722,10 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, + void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) + { + struct radeon_ring *ring = &rdev->ring[ridx]; +- u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(1) | +- SDMA_POLL_REG_MEM_EXTRA_FUNC(3)); /* == */ +- u32 ref_and_mask; + + if (vm == NULL) + return; + +- if (ridx == R600_RING_TYPE_DMA_INDEX) +- ref_and_mask = SDMA0; +- else +- ref_and_mask = SDMA1; +- + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); + if (vm->id < 8) { + radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2); +@@ -773,12 +760,7 @@ void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm + radeon_ring_write(ring, VMID(0)); + + /* flush HDP */ +- radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); +- radeon_ring_write(ring, GPU_HDP_FLUSH_DONE); +- radeon_ring_write(ring, GPU_HDP_FLUSH_REQ); +- radeon_ring_write(ring, ref_and_mask); /* REFERENCE */ +- radeon_ring_write(ring, ref_and_mask); /* MASK */ +- radeon_ring_write(ring, (4 << 16) | 10); /* RETRY_COUNT, POLL_INTERVAL */ ++ cik_sdma_hdp_flush(rdev, ring); + + /* flush TLB */ + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0004-yocto-amd-drm-radeon-allow-semaphore-emission-to-fail.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0004-yocto-amd-drm-radeon-allow-semaphore-emission-to-fail.patch new file mode 100644 index 00000000..f8d0e106 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0004-yocto-amd-drm-radeon-allow-semaphore-emission-to-fail.patch @@ -0,0 +1,754 @@ +From 26046527719672da3148501129151ccbceaf8339 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Mon, 8 Jul 2013 05:11:52 -0600 +Subject: [PATCH 04/44] drm/radeon: allow semaphore emission to fail +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some rings can only use semaphore in certain states, take that into account +and fall back to waiting for a fence when a ring currently can't emit a +semaphore. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/cik.c | 4 +- + drivers/gpu/drm/radeon/cik_sdma.c | 13 ++- + drivers/gpu/drm/radeon/evergreen_dma.c | 9 +-- + drivers/gpu/drm/radeon/r100.c | 3 +- + drivers/gpu/drm/radeon/r600.c | 13 ++- + drivers/gpu/drm/radeon/r600_dma.c | 13 ++- + drivers/gpu/drm/radeon/radeon.h | 14 ++-- + drivers/gpu/drm/radeon/radeon_asic.h | 18 ++--- + drivers/gpu/drm/radeon/radeon_cs.c | 9 ++- + drivers/gpu/drm/radeon/radeon_fence.c | 26 ++++++ + drivers/gpu/drm/radeon/radeon_gart.c | 2 +- + drivers/gpu/drm/radeon/radeon_ring.c | 46 +++-------- + drivers/gpu/drm/radeon/radeon_semaphore.c | 123 ++++++++++++++++++++++------- + drivers/gpu/drm/radeon/rv770_dma.c | 9 +-- + drivers/gpu/drm/radeon/si_dma.c | 9 +-- + drivers/gpu/drm/radeon/uvd_v1_0.c | 4 +- + drivers/gpu/drm/radeon/uvd_v3_1.c | 4 +- + 17 files changed, 182 insertions(+), 137 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index 2277a59..0608446 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -3082,7 +3082,7 @@ void cik_fence_compute_ring_emit(struct radeon_device *rdev, + cik_cp_hdp_flush(rdev, ring); + } + +-void cik_semaphore_ring_emit(struct radeon_device *rdev, ++bool cik_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait) +@@ -3093,6 +3093,8 @@ void cik_semaphore_ring_emit(struct radeon_device *rdev, + radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); + radeon_ring_write(ring, addr & 0xffffffff); + radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); ++ ++ return true; + } + + /* +diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c +index 56ede52..ace0bc6 100644 +--- a/drivers/gpu/drm/radeon/cik_sdma.c ++++ b/drivers/gpu/drm/radeon/cik_sdma.c +@@ -133,7 +133,7 @@ void cik_sdma_fence_ring_emit(struct radeon_device *rdev, + * Add a DMA semaphore packet to the ring wait on or signal + * other rings (CIK). + */ +-void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, ++bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait) +@@ -144,6 +144,8 @@ void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, + radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SEMAPHORE, 0, extra_bits)); + radeon_ring_write(ring, addr & 0xfffffff8); + radeon_ring_write(ring, upper_32_bits(addr) & 0xffffffff); ++ ++ return true; + } + + /** +@@ -446,13 +448,8 @@ int cik_copy_dma(struct radeon_device *rdev, + return r; + } + +- if (radeon_fence_need_sync(*fence, ring->idx)) { +- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, +- ring->idx); +- radeon_fence_note_sync(*fence, ring->idx); +- } else { +- radeon_semaphore_free(rdev, &sem, NULL); +- } ++ radeon_semaphore_sync_to(sem, *fence); ++ radeon_semaphore_sync_rings(rdev, sem, ring->idx); + + for (i = 0; i < num_loops; i++) { + cur_size_in_bytes = size_in_bytes; +diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c +index 6a0656d..a37b544 100644 +--- a/drivers/gpu/drm/radeon/evergreen_dma.c ++++ b/drivers/gpu/drm/radeon/evergreen_dma.c +@@ -131,13 +131,8 @@ int evergreen_copy_dma(struct radeon_device *rdev, + return r; + } + +- if (radeon_fence_need_sync(*fence, ring->idx)) { +- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, +- ring->idx); +- radeon_fence_note_sync(*fence, ring->idx); +- } else { +- radeon_semaphore_free(rdev, &sem, NULL); +- } ++ radeon_semaphore_sync_to(sem, *fence); ++ radeon_semaphore_sync_rings(rdev, sem, ring->idx); + + for (i = 0; i < num_loops; i++) { + cur_size_in_dw = size_in_dw; +diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c +index d713330..aa015a5 100644 +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -869,13 +869,14 @@ void r100_fence_ring_emit(struct radeon_device *rdev, + radeon_ring_write(ring, RADEON_SW_INT_FIRE); + } + +-void r100_semaphore_ring_emit(struct radeon_device *rdev, ++bool r100_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait) + { + /* Unused on older asics, since we don't have semaphores or multiple rings */ + BUG(); ++ return false; + } + + int r100_copy_blit(struct radeon_device *rdev, +diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c +index f9be220..a5de2cf 100644 +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -2597,7 +2597,7 @@ void r600_fence_ring_emit(struct radeon_device *rdev, + } + } + +-void r600_semaphore_ring_emit(struct radeon_device *rdev, ++bool r600_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait) +@@ -2611,6 +2611,8 @@ void r600_semaphore_ring_emit(struct radeon_device *rdev, + radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); + radeon_ring_write(ring, addr & 0xffffffff); + radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); ++ ++ return true; + } + + /** +@@ -2653,13 +2655,8 @@ int r600_copy_cpdma(struct radeon_device *rdev, + return r; + } + +- if (radeon_fence_need_sync(*fence, ring->idx)) { +- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, +- ring->idx); +- radeon_fence_note_sync(*fence, ring->idx); +- } else { +- radeon_semaphore_free(rdev, &sem, NULL); +- } ++ radeon_semaphore_sync_to(sem, *fence); ++ radeon_semaphore_sync_rings(rdev, sem, ring->idx); + + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); +diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c +index 3b31745..7844d15 100644 +--- a/drivers/gpu/drm/radeon/r600_dma.c ++++ b/drivers/gpu/drm/radeon/r600_dma.c +@@ -311,7 +311,7 @@ void r600_dma_fence_ring_emit(struct radeon_device *rdev, + * Add a DMA semaphore packet to the ring wait on or signal + * other rings (r6xx-SI). + */ +-void r600_dma_semaphore_ring_emit(struct radeon_device *rdev, ++bool r600_dma_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait) +@@ -322,6 +322,8 @@ void r600_dma_semaphore_ring_emit(struct radeon_device *rdev, + radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SEMAPHORE, 0, s, 0)); + radeon_ring_write(ring, addr & 0xfffffffc); + radeon_ring_write(ring, upper_32_bits(addr) & 0xff); ++ ++ return true; + } + + /** +@@ -462,13 +464,8 @@ int r600_copy_dma(struct radeon_device *rdev, + return r; + } + +- if (radeon_fence_need_sync(*fence, ring->idx)) { +- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, +- ring->idx); +- radeon_fence_note_sync(*fence, ring->idx); +- } else { +- radeon_semaphore_free(rdev, &sem, NULL); +- } ++ radeon_semaphore_sync_to(sem, *fence); ++ radeon_semaphore_sync_rings(rdev, sem, ring->idx); + + for (i = 0; i < num_loops; i++) { + cur_size_in_dw = size_in_dw; +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index f44ca58..c0d4230 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -348,6 +348,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, i + void radeon_fence_process(struct radeon_device *rdev, int ring); + bool radeon_fence_signaled(struct radeon_fence *fence); + int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); ++int radeon_fence_wait_locked(struct radeon_fence *fence); + int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring); + int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); + int radeon_fence_wait_any(struct radeon_device *rdev, +@@ -548,17 +549,20 @@ struct radeon_semaphore { + struct radeon_sa_bo *sa_bo; + signed waiters; + uint64_t gpu_addr; ++ struct radeon_fence *sync_to[RADEON_NUM_RINGS]; + }; + + int radeon_semaphore_create(struct radeon_device *rdev, + struct radeon_semaphore **semaphore); +-void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, ++bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, + struct radeon_semaphore *semaphore); +-void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, ++bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, + struct radeon_semaphore *semaphore); ++void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore, ++ struct radeon_fence *fence); + int radeon_semaphore_sync_rings(struct radeon_device *rdev, + struct radeon_semaphore *semaphore, +- int signaler, int waiter); ++ int waiting_ring); + void radeon_semaphore_free(struct radeon_device *rdev, + struct radeon_semaphore **semaphore, + struct radeon_fence *fence); +@@ -765,7 +769,6 @@ struct radeon_ib { + struct radeon_fence *fence; + struct radeon_vm *vm; + bool is_const_ib; +- struct radeon_fence *sync_to[RADEON_NUM_RINGS]; + struct radeon_semaphore *semaphore; + }; + +@@ -915,7 +918,6 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, + struct radeon_ib *ib, struct radeon_vm *vm, + unsigned size); + void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib); +-void radeon_ib_sync_to(struct radeon_ib *ib, struct radeon_fence *fence); + int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, + struct radeon_ib *const_ib); + int radeon_ib_pool_init(struct radeon_device *rdev); +@@ -1629,7 +1631,7 @@ struct radeon_asic_ring { + /* command emmit functions */ + void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); + void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence); +- void (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, ++ bool (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, + struct radeon_semaphore *semaphore, bool emit_wait); + void (*vm_flush)(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); + +diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h +index 70c29d5..8588670 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.h ++++ b/drivers/gpu/drm/radeon/radeon_asic.h +@@ -80,7 +80,7 @@ int r100_irq_set(struct radeon_device *rdev); + int r100_irq_process(struct radeon_device *rdev); + void r100_fence_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence); +-void r100_semaphore_ring_emit(struct radeon_device *rdev, ++bool r100_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *cp, + struct radeon_semaphore *semaphore, + bool emit_wait); +@@ -313,13 +313,13 @@ int r600_cs_parse(struct radeon_cs_parser *p); + int r600_dma_cs_parse(struct radeon_cs_parser *p); + void r600_fence_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence); +-void r600_semaphore_ring_emit(struct radeon_device *rdev, ++bool r600_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *cp, + struct radeon_semaphore *semaphore, + bool emit_wait); + void r600_dma_fence_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence); +-void r600_dma_semaphore_ring_emit(struct radeon_device *rdev, ++bool r600_dma_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait); +@@ -566,10 +566,6 @@ int sumo_dpm_force_performance_level(struct radeon_device *rdev, + */ + void cayman_fence_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence); +-void cayman_uvd_semaphore_emit(struct radeon_device *rdev, +- struct radeon_ring *ring, +- struct radeon_semaphore *semaphore, +- bool emit_wait); + void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev); + int cayman_init(struct radeon_device *rdev); + void cayman_fini(struct radeon_device *rdev); +@@ -696,7 +692,7 @@ void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); + int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); + void cik_sdma_fence_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence); +-void cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, ++bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait); +@@ -712,7 +708,7 @@ void cik_fence_gfx_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence); + void cik_fence_compute_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence); +-void cik_semaphore_ring_emit(struct radeon_device *rdev, ++bool cik_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_ring *cp, + struct radeon_semaphore *semaphore, + bool emit_wait); +@@ -802,7 +798,7 @@ void uvd_v1_0_stop(struct radeon_device *rdev); + + int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); + int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); +-void uvd_v1_0_semaphore_emit(struct radeon_device *rdev, ++bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait); +@@ -814,7 +810,7 @@ void uvd_v2_2_fence_emit(struct radeon_device *rdev, + struct radeon_fence *fence); + + /* uvd v3.1 */ +-void uvd_v3_1_semaphore_emit(struct radeon_device *rdev, ++bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait); +diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c +index 80285e3..eb5cd94 100644 +--- a/drivers/gpu/drm/radeon/radeon_cs.c ++++ b/drivers/gpu/drm/radeon/radeon_cs.c +@@ -159,7 +159,8 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p) + if (!p->relocs[i].robj) + continue; + +- radeon_ib_sync_to(&p->ib, p->relocs[i].robj->tbo.sync_obj); ++ radeon_semaphore_sync_to(p->ib.semaphore, ++ p->relocs[i].robj->tbo.sync_obj); + } + } + +@@ -495,9 +496,9 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, + goto out; + } + radeon_cs_sync_rings(parser); +- radeon_ib_sync_to(&parser->ib, vm->fence); +- radeon_ib_sync_to(&parser->ib, radeon_vm_grab_id( +- rdev, vm, parser->ring)); ++ radeon_semaphore_sync_to(parser->ib.semaphore, vm->fence); ++ radeon_semaphore_sync_to(parser->ib.semaphore, ++ radeon_vm_grab_id(rdev, vm, parser->ring)); + + if ((rdev->family >= CHIP_TAHITI) && + (parser->chunk_const_ib_idx != -1)) { +diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c +index ddb8f8e..8aea16e 100644 +--- a/drivers/gpu/drm/radeon/radeon_fence.c ++++ b/drivers/gpu/drm/radeon/radeon_fence.c +@@ -404,6 +404,32 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) + return 0; + } + ++/** ++ * radeon_fence_wait_locked - wait for a fence to signal ++ * ++ * @fence: radeon fence object ++ * ++ * Wait for the requested fence to signal (all asics). ++ * Returns 0 if the fence has passed, error for all other cases. ++ */ ++int radeon_fence_wait_locked(struct radeon_fence *fence) ++{ ++ int r; ++ ++ if (fence == NULL) { ++ WARN(1, "Querying an invalid fence : %p !\n", fence); ++ return -EINVAL; ++ } ++ ++ r = radeon_fence_wait_seq(fence->rdev, fence->seq, ++ fence->ring, false, false); ++ if (r) { ++ return r; ++ } ++ fence->seq = RADEON_FENCE_SIGNALED_SEQ; ++ return 0; ++} ++ + static bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq) + { + unsigned i; +diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c +index 3b1de72..f8d7b16 100644 +--- a/drivers/gpu/drm/radeon/radeon_gart.c ++++ b/drivers/gpu/drm/radeon/radeon_gart.c +@@ -1169,7 +1169,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, + radeon_vm_update_ptes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset, + addr, bo_va->flags); + +- radeon_ib_sync_to(&ib, vm->fence); ++ radeon_semaphore_sync_to(ib.semaphore, vm->fence); + r = radeon_ib_schedule(rdev, &ib, NULL); + if (r) { + radeon_ib_free(rdev, &ib); +diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c +index 18254e1..9214403 100644 +--- a/drivers/gpu/drm/radeon/radeon_ring.c ++++ b/drivers/gpu/drm/radeon/radeon_ring.c +@@ -61,7 +61,7 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, + struct radeon_ib *ib, struct radeon_vm *vm, + unsigned size) + { +- int i, r; ++ int r; + + r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256, true); + if (r) { +@@ -87,8 +87,6 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, + ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo); + } + ib->is_const_ib = false; +- for (i = 0; i < RADEON_NUM_RINGS; ++i) +- ib->sync_to[i] = NULL; + + return 0; + } +@@ -109,25 +107,6 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) + } + + /** +- * radeon_ib_sync_to - sync to fence before executing the IB +- * +- * @ib: IB object to add fence to +- * @fence: fence to sync to +- * +- * Sync to the fence before executing the IB +- */ +-void radeon_ib_sync_to(struct radeon_ib *ib, struct radeon_fence *fence) +-{ +- struct radeon_fence *other; +- +- if (!fence) +- return; +- +- other = ib->sync_to[fence->ring]; +- ib->sync_to[fence->ring] = radeon_fence_later(fence, other); +-} +- +-/** + * radeon_ib_schedule - schedule an IB (Indirect Buffer) on the ring + * + * @rdev: radeon_device pointer +@@ -151,8 +130,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, + struct radeon_ib *const_ib) + { + struct radeon_ring *ring = &rdev->ring[ib->ring]; +- bool need_sync = false; +- int i, r = 0; ++ int r = 0; + + if (!ib->length_dw || !ring->ready) { + /* TODO: Nothings in the ib we should report. */ +@@ -166,19 +144,15 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, + dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); + return r; + } +- for (i = 0; i < RADEON_NUM_RINGS; ++i) { +- struct radeon_fence *fence = ib->sync_to[i]; +- if (radeon_fence_need_sync(fence, ib->ring)) { +- need_sync = true; +- radeon_semaphore_sync_rings(rdev, ib->semaphore, +- fence->ring, ib->ring); +- radeon_fence_note_sync(fence, ib->ring); +- } +- } +- /* immediately free semaphore when we don't need to sync */ +- if (!need_sync) { +- radeon_semaphore_free(rdev, &ib->semaphore, NULL); ++ ++ /* sync with other rings */ ++ r = radeon_semaphore_sync_rings(rdev, ib->semaphore, ib->ring); ++ if (r) { ++ dev_err(rdev->dev, "failed to sync rings (%d)\n", r); ++ radeon_ring_unlock_undo(rdev, ring); ++ return r; + } ++ + /* if we can't remember our last VM flush then flush now! */ + /* XXX figure out why we have to flush for every IB */ + if (ib->vm /*&& !ib->vm->last_flush*/) { +diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c +index 8dcc20f..34ea889 100644 +--- a/drivers/gpu/drm/radeon/radeon_semaphore.c ++++ b/drivers/gpu/drm/radeon/radeon_semaphore.c +@@ -34,7 +34,7 @@ + int radeon_semaphore_create(struct radeon_device *rdev, + struct radeon_semaphore **semaphore) + { +- int r; ++ int i, r; + + *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); + if (*semaphore == NULL) { +@@ -50,54 +50,117 @@ int radeon_semaphore_create(struct radeon_device *rdev, + (*semaphore)->waiters = 0; + (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); + *((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; ++ ++ for (i = 0; i < RADEON_NUM_RINGS; ++i) ++ (*semaphore)->sync_to[i] = NULL; ++ + return 0; + } + +-void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, ++bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ridx, + struct radeon_semaphore *semaphore) + { +- --semaphore->waiters; +- radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false); ++ struct radeon_ring *ring = &rdev->ring[ridx]; ++ ++ if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, false)) { ++ --semaphore->waiters; ++ ++ /* for debugging lockup only, used by sysfs debug files */ ++ ring->last_semaphore_signal_addr = semaphore->gpu_addr; ++ return true; ++ } ++ return false; + } + +-void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, ++bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx, + struct radeon_semaphore *semaphore) + { +- ++semaphore->waiters; +- radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true); ++ struct radeon_ring *ring = &rdev->ring[ridx]; ++ ++ if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, true)) { ++ ++semaphore->waiters; ++ ++ /* for debugging lockup only, used by sysfs debug files */ ++ ring->last_semaphore_wait_addr = semaphore->gpu_addr; ++ return true; ++ } ++ return false; + } + +-/* caller must hold ring lock */ ++/** ++ * radeon_semaphore_sync_to - use the semaphore to sync to a fence ++ * ++ * @semaphore: semaphore object to add fence to ++ * @fence: fence to sync to ++ * ++ * Sync to the fence using this semaphore object ++ */ ++void radeon_semaphore_sync_to(struct radeon_semaphore *semaphore, ++ struct radeon_fence *fence) ++{ ++ struct radeon_fence *other; ++ ++ if (!fence) ++ return; ++ ++ other = semaphore->sync_to[fence->ring]; ++ semaphore->sync_to[fence->ring] = radeon_fence_later(fence, other); ++} ++ ++/** ++ * radeon_semaphore_sync_rings - sync ring to all registered fences ++ * ++ * @rdev: radeon_device pointer ++ * @semaphore: semaphore object to use for sync ++ * @ring: ring that needs sync ++ * ++ * Ensure that all registered fences are signaled before letting ++ * the ring continue. The caller must hold the ring lock. ++ */ + int radeon_semaphore_sync_rings(struct radeon_device *rdev, + struct radeon_semaphore *semaphore, +- int signaler, int waiter) ++ int ring) + { +- int r; ++ int i, r; + +- /* no need to signal and wait on the same ring */ +- if (signaler == waiter) { +- return 0; +- } ++ for (i = 0; i < RADEON_NUM_RINGS; ++i) { ++ struct radeon_fence *fence = semaphore->sync_to[i]; + +- /* prevent GPU deadlocks */ +- if (!rdev->ring[signaler].ready) { +- dev_err(rdev->dev, "Trying to sync to a disabled ring!"); +- return -EINVAL; +- } ++ /* check if we really need to sync */ ++ if (!radeon_fence_need_sync(fence, ring)) ++ continue; + +- r = radeon_ring_alloc(rdev, &rdev->ring[signaler], 8); +- if (r) { +- return r; +- } +- radeon_semaphore_emit_signal(rdev, signaler, semaphore); +- radeon_ring_commit(rdev, &rdev->ring[signaler]); ++ /* prevent GPU deadlocks */ ++ if (!rdev->ring[i].ready) { ++ dev_err(rdev->dev, "Syncing to a disabled ring!"); ++ return -EINVAL; ++ } + +- /* we assume caller has already allocated space on waiters ring */ +- radeon_semaphore_emit_wait(rdev, waiter, semaphore); ++ /* allocate enough space for sync command */ ++ r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); ++ if (r) { ++ return r; ++ } + +- /* for debugging lockup only, used by sysfs debug files */ +- rdev->ring[signaler].last_semaphore_signal_addr = semaphore->gpu_addr; +- rdev->ring[waiter].last_semaphore_wait_addr = semaphore->gpu_addr; ++ /* emit the signal semaphore */ ++ if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) { ++ /* signaling wasn't successful wait manually */ ++ radeon_ring_undo(&rdev->ring[i]); ++ radeon_fence_wait_locked(fence); ++ continue; ++ } ++ ++ /* we assume caller has already allocated space on waiters ring */ ++ if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) { ++ /* waiting wasn't successful wait manually */ ++ radeon_ring_undo(&rdev->ring[i]); ++ radeon_fence_wait_locked(fence); ++ continue; ++ } ++ ++ radeon_ring_commit(rdev, &rdev->ring[i]); ++ radeon_fence_note_sync(fence, ring); ++ } + + return 0; + } +diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c +index f9b02e3..aca8cbe 100644 +--- a/drivers/gpu/drm/radeon/rv770_dma.c ++++ b/drivers/gpu/drm/radeon/rv770_dma.c +@@ -66,13 +66,8 @@ int rv770_copy_dma(struct radeon_device *rdev, + return r; + } + +- if (radeon_fence_need_sync(*fence, ring->idx)) { +- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, +- ring->idx); +- radeon_fence_note_sync(*fence, ring->idx); +- } else { +- radeon_semaphore_free(rdev, &sem, NULL); +- } ++ radeon_semaphore_sync_to(sem, *fence); ++ radeon_semaphore_sync_rings(rdev, sem, ring->idx); + + for (i = 0; i < num_loops; i++) { + cur_size_in_dw = size_in_dw; +diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c +index 17205fd..97af34c 100644 +--- a/drivers/gpu/drm/radeon/si_dma.c ++++ b/drivers/gpu/drm/radeon/si_dma.c +@@ -202,13 +202,8 @@ int si_copy_dma(struct radeon_device *rdev, + return r; + } + +- if (radeon_fence_need_sync(*fence, ring->idx)) { +- radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, +- ring->idx); +- radeon_fence_note_sync(*fence, ring->idx); +- } else { +- radeon_semaphore_free(rdev, &sem, NULL); +- } ++ radeon_semaphore_sync_to(sem, *fence); ++ radeon_semaphore_sync_rings(rdev, sem, ring->idx); + + for (i = 0; i < num_loops; i++) { + cur_size_in_bytes = size_in_bytes; +diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c +index 7266805..d4a68af 100644 +--- a/drivers/gpu/drm/radeon/uvd_v1_0.c ++++ b/drivers/gpu/drm/radeon/uvd_v1_0.c +@@ -357,7 +357,7 @@ int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) + * + * Emit a semaphore command (either wait or signal) to the UVD ring. + */ +-void uvd_v1_0_semaphore_emit(struct radeon_device *rdev, ++bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait) +@@ -372,6 +372,8 @@ void uvd_v1_0_semaphore_emit(struct radeon_device *rdev, + + radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); + radeon_ring_write(ring, emit_wait ? 1 : 0); ++ ++ return true; + } + + /** +diff --git a/drivers/gpu/drm/radeon/uvd_v3_1.c b/drivers/gpu/drm/radeon/uvd_v3_1.c +index 5b6fa1f..d722db2 100644 +--- a/drivers/gpu/drm/radeon/uvd_v3_1.c ++++ b/drivers/gpu/drm/radeon/uvd_v3_1.c +@@ -37,7 +37,7 @@ + * + * Emit a semaphore command (either wait or signal) to the UVD ring. + */ +-void uvd_v3_1_semaphore_emit(struct radeon_device *rdev, ++bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_semaphore *semaphore, + bool emit_wait) +@@ -52,4 +52,6 @@ void uvd_v3_1_semaphore_emit(struct radeon_device *rdev, + + radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); + radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0)); ++ ++ return true; + } +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0005-yocto-amd-drm-radeon-improve-ring-debugfs-a-bit.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0005-yocto-amd-drm-radeon-improve-ring-debugfs-a-bit.patch new file mode 100644 index 00000000..b46ce725 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0005-yocto-amd-drm-radeon-improve-ring-debugfs-a-bit.patch @@ -0,0 +1,93 @@ +From e628d1bcf988fe77d8b040d00c97eb20645758ab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Tue, 12 Nov 2013 10:55:12 -0700 +Subject: [PATCH 05/44] drm/radeon: improve ring debugfs a bit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon_ring.c | 56 +++++++++++++++++++++++----------- + 1 file changed, 38 insertions(+), 18 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c +index 9214403..f1cec22 100644 +--- a/drivers/gpu/drm/radeon/radeon_ring.c ++++ b/drivers/gpu/drm/radeon/radeon_ring.c +@@ -790,34 +790,54 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) + struct radeon_device *rdev = dev->dev_private; + int ridx = *(int*)node->info_ent->data; + struct radeon_ring *ring = &rdev->ring[ridx]; ++ ++ uint32_t rptr, wptr, rptr_next; + unsigned count, i, j; +- u32 tmp; + + radeon_ring_free_size(rdev, ring); + count = (ring->ring_size / 4) - ring->ring_free_dw; +- tmp = radeon_ring_get_wptr(rdev, ring); +- seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", ring->wptr_reg, tmp, tmp); +- tmp = radeon_ring_get_rptr(rdev, ring); +- seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", ring->rptr_reg, tmp, tmp); ++ ++ wptr = radeon_ring_get_wptr(rdev, ring); ++ seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", ++ ring->wptr_reg, wptr, wptr); ++ ++ rptr = radeon_ring_get_rptr(rdev, ring); ++ seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", ++ ring->rptr_reg, rptr, rptr); ++ + if (ring->rptr_save_reg) { +- seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg, +- RREG32(ring->rptr_save_reg)); +- } +- seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", ring->wptr, ring->wptr); +- seq_printf(m, "driver's copy of the rptr: 0x%08x [%5d]\n", ring->rptr, ring->rptr); +- seq_printf(m, "last semaphore signal addr : 0x%016llx\n", ring->last_semaphore_signal_addr); +- seq_printf(m, "last semaphore wait addr : 0x%016llx\n", ring->last_semaphore_wait_addr); ++ rptr_next = RREG32(ring->rptr_save_reg); ++ seq_printf(m, "rptr next(0x%04x): 0x%08x [%5d]\n", ++ ring->rptr_save_reg, rptr_next, rptr_next); ++ } else ++ rptr_next = ~0; ++ ++ seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", ++ ring->wptr, ring->wptr); ++ seq_printf(m, "driver's copy of the rptr: 0x%08x [%5d]\n", ++ ring->rptr, ring->rptr); ++ seq_printf(m, "last semaphore signal addr : 0x%016llx\n", ++ ring->last_semaphore_signal_addr); ++ seq_printf(m, "last semaphore wait addr : 0x%016llx\n", ++ ring->last_semaphore_wait_addr); + seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); + seq_printf(m, "%u dwords in ring\n", count); ++ ++ if (!ring->ready) ++ return 0; ++ + /* print 8 dw before current rptr as often it's the last executed + * packet that is the root issue + */ +- i = (ring->rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask; +- if (ring->ready) { +- for (j = 0; j <= (count + 32); j++) { +- seq_printf(m, "r[%5d]=0x%08x\n", i, ring->ring[i]); +- i = (i + 1) & ring->ptr_mask; +- } ++ i = (rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask; ++ for (j = 0; j <= (count + 32); j++) { ++ seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]); ++ if (rptr == i) ++ seq_puts(m, " *"); ++ if (rptr_next == i) ++ seq_puts(m, " #"); ++ seq_puts(m, "\n"); ++ i = (i + 1) & ring->ptr_mask; + } + return 0; + } +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0006-yocto-amd-drm-radeon-report-the-real-offset-in-radeon_sa_bo_du.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0006-yocto-amd-drm-radeon-report-the-real-offset-in-radeon_sa_bo_du.patch new file mode 100644 index 00000000..7ddaa18f --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0006-yocto-amd-drm-radeon-report-the-real-offset-in-radeon_sa_bo_du.patch @@ -0,0 +1,39 @@ +From cf27c1b111dd09e7f55feb28de6d8f80fd28fd67 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Tue, 10 Dec 2013 12:46:23 -0700 +Subject: [PATCH 06/44] drm/radeon: report the real offset in + radeon_sa_bo_dump_debug_info +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon_sa.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c +index f0bac68..c062580 100644 +--- a/drivers/gpu/drm/radeon/radeon_sa.c ++++ b/drivers/gpu/drm/radeon/radeon_sa.c +@@ -402,13 +402,15 @@ void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager, + + spin_lock(&sa_manager->wq.lock); + list_for_each_entry(i, &sa_manager->olist, olist) { ++ uint64_t soffset = i->soffset + sa_manager->gpu_addr; ++ uint64_t eoffset = i->eoffset + sa_manager->gpu_addr; + if (&i->olist == sa_manager->hole) { + seq_printf(m, ">"); + } else { + seq_printf(m, " "); + } +- seq_printf(m, "[0x%08x 0x%08x] size %8d", +- i->soffset, i->eoffset, i->eoffset - i->soffset); ++ seq_printf(m, "[0x%010llx 0x%010llx] size %8lld", ++ soffset, eoffset, eoffset - soffset); + if (i->fence) { + seq_printf(m, " protected by 0x%016llx on ring %d", + i->fence->seq, i->fence->ring); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0007-yocto-amd-drm-radeon-update-fence-values-in-before-reporting-t.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0007-yocto-amd-drm-radeon-update-fence-values-in-before-reporting-t.patch new file mode 100644 index 00000000..ebc32a16 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0007-yocto-amd-drm-radeon-update-fence-values-in-before-reporting-t.patch @@ -0,0 +1,30 @@ +From c6c27a74ed822d853de89e5d1360b983906e35aa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Tue, 10 Dec 2013 12:48:45 -0700 +Subject: [PATCH 07/44] drm/radeon: update fence values in before reporting + them +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon_fence.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c +index 8aea16e..51760b7 100644 +--- a/drivers/gpu/drm/radeon/radeon_fence.c ++++ b/drivers/gpu/drm/radeon/radeon_fence.c +@@ -945,6 +945,8 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data) + if (!rdev->fence_drv[i].initialized) + continue; + ++ radeon_fence_process(rdev, i); ++ + seq_printf(m, "--- ring %d ---\n", i); + seq_printf(m, "Last signaled fence 0x%016llx\n", + (unsigned long long)atomic64_read(&rdev->fence_drv[i].last_seq)); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0008-yocto-amd-drm-radeon-cleanup-radeon_ttm-debugfs-handling.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0008-yocto-amd-drm-radeon-cleanup-radeon_ttm-debugfs-handling.patch new file mode 100644 index 00000000..bb62cdb6 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0008-yocto-amd-drm-radeon-cleanup-radeon_ttm-debugfs-handling.patch @@ -0,0 +1,109 @@ +From d1ed06d2f21d3e7b407e4b32739472b7210c95ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Mon, 9 Dec 2013 06:50:21 -0700 +Subject: [PATCH 08/44] drm/radeon: cleanup radeon_ttm debugfs handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Otherwise we not necessary export the right information. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon_ttm.c | 59 ++++++++++++++--------------------- + 1 file changed, 23 insertions(+), 36 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c +index 71245d6..a2d6c4f 100644 +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -832,16 +832,15 @@ int radeon_mmap(struct file *filp, struct vm_area_struct *vma) + return 0; + } + +- +-#define RADEON_DEBUGFS_MEM_TYPES 2 +- + #if defined(CONFIG_DEBUG_FS) ++ + static int radeon_mm_dump_table(struct seq_file *m, void *data) + { + struct drm_info_node *node = (struct drm_info_node *)m->private; +- struct drm_mm *mm = (struct drm_mm *)node->info_ent->data; ++ unsigned ttm_pl = *(int *)node->info_ent->data; + struct drm_device *dev = node->minor->dev; + struct radeon_device *rdev = dev->dev_private; ++ struct drm_mm *mm = (struct drm_mm *)rdev->mman.bdev.man[ttm_pl].priv; + int ret; + struct ttm_bo_global *glob = rdev->mman.bdev.glob; + +@@ -850,46 +849,34 @@ static int radeon_mm_dump_table(struct seq_file *m, void *data) + spin_unlock(&glob->lru_lock); + return ret; + } ++ ++static int ttm_pl_vram = TTM_PL_VRAM; ++static int ttm_pl_tt = TTM_PL_TT; ++ ++static struct drm_info_list radeon_ttm_debugfs_list[] = { ++ {"radeon_vram_mm", radeon_mm_dump_table, 0, &ttm_pl_vram}, ++ {"radeon_gtt_mm", radeon_mm_dump_table, 0, &ttm_pl_tt}, ++ {"ttm_page_pool", ttm_page_alloc_debugfs, 0, NULL}, ++#ifdef CONFIG_SWIOTLB ++ {"ttm_dma_page_pool", ttm_dma_page_alloc_debugfs, 0, NULL} ++#endif ++}; ++ + #endif + + static int radeon_ttm_debugfs_init(struct radeon_device *rdev) + { + #if defined(CONFIG_DEBUG_FS) +- static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES+2]; +- static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES+2][32]; +- unsigned i; ++ unsigned count = ARRAY_SIZE(radeon_ttm_debugfs_list); + +- for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) { +- if (i == 0) +- sprintf(radeon_mem_types_names[i], "radeon_vram_mm"); +- else +- sprintf(radeon_mem_types_names[i], "radeon_gtt_mm"); +- radeon_mem_types_list[i].name = radeon_mem_types_names[i]; +- radeon_mem_types_list[i].show = &radeon_mm_dump_table; +- radeon_mem_types_list[i].driver_features = 0; +- if (i == 0) +- radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_VRAM].priv; +- else +- radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_TT].priv; +- +- } +- /* Add ttm page pool to debugfs */ +- sprintf(radeon_mem_types_names[i], "ttm_page_pool"); +- radeon_mem_types_list[i].name = radeon_mem_types_names[i]; +- radeon_mem_types_list[i].show = &ttm_page_alloc_debugfs; +- radeon_mem_types_list[i].driver_features = 0; +- radeon_mem_types_list[i++].data = NULL; + #ifdef CONFIG_SWIOTLB +- if (swiotlb_nr_tbl()) { +- sprintf(radeon_mem_types_names[i], "ttm_dma_page_pool"); +- radeon_mem_types_list[i].name = radeon_mem_types_names[i]; +- radeon_mem_types_list[i].show = &ttm_dma_page_alloc_debugfs; +- radeon_mem_types_list[i].driver_features = 0; +- radeon_mem_types_list[i++].data = NULL; +- } ++ if (!swiotlb_nr_tbl()) ++ --count; + #endif +- return radeon_debugfs_add_files(rdev, radeon_mem_types_list, i); + +-#endif ++ return radeon_debugfs_add_files(rdev, radeon_ttm_debugfs_list, count); ++#else ++ + return 0; ++#endif + } +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0009-yocto-amd-drm-radeon-add-VRAM-debugfs-access-v3.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0009-yocto-amd-drm-radeon-add-VRAM-debugfs-access-v3.patch new file mode 100644 index 00000000..c8788bd6 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0009-yocto-amd-drm-radeon-add-VRAM-debugfs-access-v3.patch @@ -0,0 +1,168 @@ +From c100632a7a63c7cc03b7c4ad391477c919c61666 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Tue, 10 Dec 2013 07:45:24 -0700 +Subject: [PATCH 09/44] drm/radeon: add VRAM debugfs access v3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Not very fast, but makes it possible to access even the +normally inaccessible parts of VRAM from userspace. + +v2: use MM_INDEX_HI for >2GB mem access, add default_llseek +v3: set inode size in the open callback + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/evergreen_reg.h | 1 + + drivers/gpu/drm/radeon/radeon.h | 4 ++ + drivers/gpu/drm/radeon/radeon_ttm.c | 77 +++++++++++++++++++++++++++++++- + 3 files changed, 81 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h +index 8a4e641..a0f63ff 100644 +--- a/drivers/gpu/drm/radeon/evergreen_reg.h ++++ b/drivers/gpu/drm/radeon/evergreen_reg.h +@@ -33,6 +33,7 @@ + #define EVERGREEN_PIF_PHY0_DATA 0xc + #define EVERGREEN_PIF_PHY1_INDEX 0x10 + #define EVERGREEN_PIF_PHY1_DATA 0x14 ++#define EVERGREEN_MM_INDEX_HI 0x18 + + #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS 0x310 + #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH 0x324 +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index c0d4230..14df551 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -413,6 +413,10 @@ struct radeon_mman { + struct ttm_bo_device bdev; + bool mem_global_referenced; + bool initialized; ++ ++#if defined(CONFIG_DEBUG_FS) ++ struct dentry *vram; ++#endif + }; + + /* bo virtual address in a specific vm */ +diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c +index a2d6c4f..83ef24d 100644 +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -39,12 +39,14 @@ + #include <linux/seq_file.h> + #include <linux/slab.h> + #include <linux/swiotlb.h> ++#include <linux/debugfs.h> + #include "radeon_reg.h" + #include "radeon.h" + + #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) + + static int radeon_ttm_debugfs_init(struct radeon_device *rdev); ++static void radeon_ttm_debugfs_fini(struct radeon_device *rdev); + + static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) + { +@@ -753,6 +755,7 @@ void radeon_ttm_fini(struct radeon_device *rdev) + + if (!rdev->mman.initialized) + return; ++ radeon_ttm_debugfs_fini(rdev); + if (rdev->stollen_vga_memory) { + r = radeon_bo_reserve(rdev->stollen_vga_memory, false); + if (r == 0) { +@@ -862,12 +865,75 @@ static struct drm_info_list radeon_ttm_debugfs_list[] = { + #endif + }; + ++static int radeon_ttm_vram_open(struct inode *inode, struct file *filep) ++{ ++ struct radeon_device *rdev = inode->i_private; ++ i_size_write(inode, rdev->mc.mc_vram_size); ++ filep->private_data = inode->i_private; ++ return 0; ++} ++ ++static ssize_t radeon_ttm_vram_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct radeon_device *rdev = f->private_data; ++ ssize_t result = 0; ++ int r; ++ ++ if (size & 0x3 || *pos & 0x3) ++ return -EINVAL; ++ ++ while (size) { ++ unsigned long flags; ++ uint32_t value; ++ ++ if (*pos >= rdev->mc.mc_vram_size) ++ return result; ++ ++ spin_lock_irqsave(&rdev->mmio_idx_lock, flags); ++ WREG32(RADEON_MM_INDEX, ((uint32_t)*pos) | 0x80000000); ++ if (rdev->family >= CHIP_CEDAR) ++ WREG32(EVERGREEN_MM_INDEX_HI, *pos >> 31); ++ value = RREG32(RADEON_MM_DATA); ++ spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags); ++ ++ r = put_user(value, (uint32_t *)buf); ++ if (r) ++ return r; ++ ++ result += 4; ++ buf += 4; ++ *pos += 4; ++ size -= 4; ++ } ++ ++ return result; ++} ++ ++static const struct file_operations radeon_ttm_vram_fops = { ++ .owner = THIS_MODULE, ++ .open = radeon_ttm_vram_open, ++ .read = radeon_ttm_vram_read, ++ .llseek = default_llseek ++}; ++ + #endif + + static int radeon_ttm_debugfs_init(struct radeon_device *rdev) + { + #if defined(CONFIG_DEBUG_FS) +- unsigned count = ARRAY_SIZE(radeon_ttm_debugfs_list); ++ unsigned count; ++ ++ struct drm_minor *minor = rdev->ddev->primary; ++ struct dentry *ent, *root = minor->debugfs_root; ++ ++ ent = debugfs_create_file("radeon_vram", S_IFREG | S_IRUGO, root, ++ rdev, &radeon_ttm_vram_fops); ++ if (IS_ERR(ent)) ++ return PTR_ERR(ent); ++ rdev->mman.vram = ent; ++ ++ count = ARRAY_SIZE(radeon_ttm_debugfs_list); + + #ifdef CONFIG_SWIOTLB + if (!swiotlb_nr_tbl()) +@@ -880,3 +946,12 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev) + return 0; + #endif + } ++ ++static void radeon_ttm_debugfs_fini(struct radeon_device *rdev) ++{ ++#if defined(CONFIG_DEBUG_FS) ++ ++ debugfs_remove(rdev->mman.vram); ++ rdev->mman.vram = NULL; ++#endif ++} +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0010-yocto-amd-drm-radeon-add-GART-debugfs-access-v3.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0010-yocto-amd-drm-radeon-add-GART-debugfs-access-v3.patch new file mode 100644 index 00000000..5cabdf25 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0010-yocto-amd-drm-radeon-add-GART-debugfs-access-v3.patch @@ -0,0 +1,119 @@ +From ee6e4aae828077d7503a2baf5acb54df222fa922 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Wed, 11 Dec 2013 06:13:22 -0700 +Subject: [PATCH 10/44] drm/radeon: add GART debugfs access v3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +v2: add default_llseek +v3: set inode size in the open callback + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 1 + + drivers/gpu/drm/radeon/radeon_ttm.c | 63 +++++++++++++++++++++++++++++++++++ + 2 files changed, 64 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 14df551..7a483c9 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -416,6 +416,7 @@ struct radeon_mman { + + #if defined(CONFIG_DEBUG_FS) + struct dentry *vram; ++ struct dentry *gtt; + #endif + }; + +diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c +index 83ef24d..381782d 100644 +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -917,6 +917,60 @@ static const struct file_operations radeon_ttm_vram_fops = { + .llseek = default_llseek + }; + ++static int radeon_ttm_gtt_open(struct inode *inode, struct file *filep) ++{ ++ struct radeon_device *rdev = inode->i_private; ++ i_size_write(inode, rdev->mc.gtt_size); ++ filep->private_data = inode->i_private; ++ return 0; ++} ++ ++static ssize_t radeon_ttm_gtt_read(struct file *f, char __user *buf, ++ size_t size, loff_t *pos) ++{ ++ struct radeon_device *rdev = f->private_data; ++ ssize_t result = 0; ++ int r; ++ ++ while (size) { ++ loff_t p = *pos / PAGE_SIZE; ++ unsigned off = *pos & ~PAGE_MASK; ++ ssize_t cur_size = min(size, PAGE_SIZE - off); ++ struct page *page; ++ void *ptr; ++ ++ if (p >= rdev->gart.num_cpu_pages) ++ return result; ++ ++ page = rdev->gart.pages[p]; ++ if (page) { ++ ptr = kmap(page); ++ ptr += off; ++ ++ r = copy_to_user(buf, ptr, cur_size); ++ kunmap(rdev->gart.pages[p]); ++ } else ++ r = clear_user(buf, cur_size); ++ ++ if (r) ++ return -EFAULT; ++ ++ result += cur_size; ++ buf += cur_size; ++ *pos += cur_size; ++ size -= cur_size; ++ } ++ ++ return result; ++} ++ ++static const struct file_operations radeon_ttm_gtt_fops = { ++ .owner = THIS_MODULE, ++ .open = radeon_ttm_gtt_open, ++ .read = radeon_ttm_gtt_read, ++ .llseek = default_llseek ++}; ++ + #endif + + static int radeon_ttm_debugfs_init(struct radeon_device *rdev) +@@ -933,6 +987,12 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev) + return PTR_ERR(ent); + rdev->mman.vram = ent; + ++ ent = debugfs_create_file("radeon_gtt", S_IFREG | S_IRUGO, root, ++ rdev, &radeon_ttm_gtt_fops); ++ if (IS_ERR(ent)) ++ return PTR_ERR(ent); ++ rdev->mman.gtt = ent; ++ + count = ARRAY_SIZE(radeon_ttm_debugfs_list); + + #ifdef CONFIG_SWIOTLB +@@ -953,5 +1013,8 @@ static void radeon_ttm_debugfs_fini(struct radeon_device *rdev) + + debugfs_remove(rdev->mman.vram); + rdev->mman.vram = NULL; ++ ++ debugfs_remove(rdev->mman.gtt); ++ rdev->mman.gtt = NULL; + #endif + } +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0011-yocto-amd-drm-radeon-fix-VMID-use-tracking.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0011-yocto-amd-drm-radeon-fix-VMID-use-tracking.patch new file mode 100644 index 00000000..40486c39 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0011-yocto-amd-drm-radeon-fix-VMID-use-tracking.patch @@ -0,0 +1,71 @@ +From cdf069ae98745bb458f38ec7267fe80a544ddee1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Sat, 14 Dec 2013 10:02:57 -0700 +Subject: [PATCH 11/44] drm/radeon: fix VMID use tracking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Otherwise we allocate a new VMID on nearly every submit. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 2 ++ + drivers/gpu/drm/radeon/radeon_gart.c | 8 +++++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 7a483c9..a21b1d4 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -857,6 +857,8 @@ struct radeon_vm { + struct radeon_fence *fence; + /* last flush or NULL if we still need to flush */ + struct radeon_fence *last_flush; ++ /* last use of vmid */ ++ struct radeon_fence *last_id_use; + }; + + struct radeon_vm_manager { +diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c +index f8d7b16..cdab083 100644 +--- a/drivers/gpu/drm/radeon/radeon_gart.c ++++ b/drivers/gpu/drm/radeon/radeon_gart.c +@@ -688,7 +688,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, + unsigned i; + + /* check if the id is still valid */ +- if (vm->fence && vm->fence == rdev->vm_manager.active[vm->id]) ++ if (vm->last_id_use && vm->last_id_use == rdev->vm_manager.active[vm->id]) + return NULL; + + /* we definately need to flush */ +@@ -743,6 +743,9 @@ void radeon_vm_fence(struct radeon_device *rdev, + + radeon_fence_unref(&vm->fence); + vm->fence = radeon_fence_ref(fence); ++ ++ radeon_fence_unref(&vm->last_id_use); ++ vm->last_id_use = radeon_fence_ref(fence); + } + + /** +@@ -1246,6 +1249,8 @@ void radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) + { + vm->id = 0; + vm->fence = NULL; ++ vm->last_flush = NULL; ++ vm->last_id_use = NULL; + mutex_init(&vm->mutex); + INIT_LIST_HEAD(&vm->list); + INIT_LIST_HEAD(&vm->va); +@@ -1284,5 +1289,6 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) + } + radeon_fence_unref(&vm->fence); + radeon_fence_unref(&vm->last_flush); ++ radeon_fence_unref(&vm->last_id_use); + mutex_unlock(&vm->mutex); + } +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0012-yocto-amd-drm-radeon-add-missing-trace-point.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0012-yocto-amd-drm-radeon-add-missing-trace-point.patch new file mode 100644 index 00000000..f6f82bba --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0012-yocto-amd-drm-radeon-add-missing-trace-point.patch @@ -0,0 +1,28 @@ +From 6674c82f2a3cb9da12768e3670a814e84f9e54cc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Sat, 14 Dec 2013 04:11:08 -0700 +Subject: [PATCH 12/44] drm/radeon: add missing trace point +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon_gart.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c +index cdab083..d1077f6 100644 +--- a/drivers/gpu/drm/radeon/radeon_gart.c ++++ b/drivers/gpu/drm/radeon/radeon_gart.c +@@ -701,6 +701,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, + if (fence == NULL) { + /* found a free one */ + vm->id = i; ++ trace_radeon_vm_grab_id(vm->id, ring); + return NULL; + } + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0013-yocto-amd-drm-radeon-add-semaphore-trace-point.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0013-yocto-amd-drm-radeon-add-semaphore-trace-point.patch new file mode 100644 index 00000000..b63f8c9a --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0013-yocto-amd-drm-radeon-add-semaphore-trace-point.patch @@ -0,0 +1,95 @@ +From e5798e4519e07f3f0c6077a6f5dd2e9223d01f85 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 7 Nov 2013 05:32:33 -0700 +Subject: [PATCH 13/44] drm/radeon: add semaphore trace point +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon_semaphore.c | 6 ++++- + drivers/gpu/drm/radeon/radeon_trace.h | 36 +++++++++++++++++++++++++++++ + 2 files changed, 41 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c +index 34ea889..2b42aa1 100644 +--- a/drivers/gpu/drm/radeon/radeon_semaphore.c ++++ b/drivers/gpu/drm/radeon/radeon_semaphore.c +@@ -29,7 +29,7 @@ + */ + #include <drm/drmP.h> + #include "radeon.h" +- ++#include "radeon_trace.h" + + int radeon_semaphore_create(struct radeon_device *rdev, + struct radeon_semaphore **semaphore) +@@ -62,6 +62,8 @@ bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ridx, + { + struct radeon_ring *ring = &rdev->ring[ridx]; + ++ trace_radeon_semaphore_signale(ridx, semaphore); ++ + if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, false)) { + --semaphore->waiters; + +@@ -77,6 +79,8 @@ bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx, + { + struct radeon_ring *ring = &rdev->ring[ridx]; + ++ trace_radeon_semaphore_wait(ridx, semaphore); ++ + if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, true)) { + ++semaphore->waiters; + +diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h +index 811bca6..9f0e181 100644 +--- a/drivers/gpu/drm/radeon/radeon_trace.h ++++ b/drivers/gpu/drm/radeon/radeon_trace.h +@@ -111,6 +111,42 @@ DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_end, + TP_ARGS(dev, seqno) + ); + ++DECLARE_EVENT_CLASS(radeon_semaphore_request, ++ ++ TP_PROTO(int ring, struct radeon_semaphore *sem), ++ ++ TP_ARGS(ring, sem), ++ ++ TP_STRUCT__entry( ++ __field(int, ring) ++ __field(signed, waiters) ++ __field(uint64_t, gpu_addr) ++ ), ++ ++ TP_fast_assign( ++ __entry->ring = ring; ++ __entry->waiters = sem->waiters; ++ __entry->gpu_addr = sem->gpu_addr; ++ ), ++ ++ TP_printk("ring=%u, waiters=%d, addr=%010Lx", __entry->ring, ++ __entry->waiters, __entry->gpu_addr) ++); ++ ++DEFINE_EVENT(radeon_semaphore_request, radeon_semaphore_signale, ++ ++ TP_PROTO(int ring, struct radeon_semaphore *sem), ++ ++ TP_ARGS(ring, sem) ++); ++ ++DEFINE_EVENT(radeon_semaphore_request, radeon_semaphore_wait, ++ ++ TP_PROTO(int ring, struct radeon_semaphore *sem), ++ ++ TP_ARGS(ring, sem) ++); ++ + #endif + + /* This part must be outside protection */ +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0014-yocto-amd-drm-radeon-add-VMID-allocation-trace-point.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0014-yocto-amd-drm-radeon-add-VMID-allocation-trace-point.patch new file mode 100644 index 00000000..4e230031 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0014-yocto-amd-drm-radeon-add-VMID-allocation-trace-point.patch @@ -0,0 +1,64 @@ +From 0a4a2069686234528f3e2c876a97bdd499062c2c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Mon, 25 Nov 2013 15:42:10 +0100 +Subject: [PATCH 14/44] drm/radeon: add VMID allocation trace point +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/radeon_gart.c | 2 ++ + drivers/gpu/drm/radeon/radeon_trace.h | 15 +++++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c +index d1077f6..f7c0b64 100644 +--- a/drivers/gpu/drm/radeon/radeon_gart.c ++++ b/drivers/gpu/drm/radeon/radeon_gart.c +@@ -29,6 +29,7 @@ + #include <drm/radeon_drm.h> + #include "radeon.h" + #include "radeon_reg.h" ++#include "radeon_trace.h" + + /* + * GART +@@ -714,6 +715,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, + for (i = 0; i < 2; ++i) { + if (choices[i]) { + vm->id = choices[i]; ++ trace_radeon_vm_grab_id(vm->id, ring); + return rdev->vm_manager.active[choices[i]]; + } + } +diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h +index 9f0e181..8c13aec 100644 +--- a/drivers/gpu/drm/radeon/radeon_trace.h ++++ b/drivers/gpu/drm/radeon/radeon_trace.h +@@ -47,6 +47,21 @@ TRACE_EVENT(radeon_cs, + __entry->fences) + ); + ++TRACE_EVENT(radeon_vm_grab_id, ++ TP_PROTO(unsigned vmid, int ring), ++ TP_ARGS(vmid, ring), ++ TP_STRUCT__entry( ++ __field(u32, vmid) ++ __field(u32, ring) ++ ), ++ ++ TP_fast_assign( ++ __entry->vmid = vmid; ++ __entry->ring = ring; ++ ), ++ TP_printk("vmid=%u, ring=%u", __entry->vmid, __entry->ring) ++); ++ + TRACE_EVENT(radeon_vm_set_page, + TP_PROTO(uint64_t pe, uint64_t addr, unsigned count, + uint32_t incr, uint32_t flags), +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0015-yocto-amd-drm-radeon-add-uvd-debugfs-support.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0015-yocto-amd-drm-radeon-add-uvd-debugfs-support.patch new file mode 100644 index 00000000..fd312353 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0015-yocto-amd-drm-radeon-add-uvd-debugfs-support.patch @@ -0,0 +1,99 @@ +From 627d32e67d83a65294cb9da1e7ef796009b0e5d8 Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Mon, 25 Nov 2013 17:25:41 -0500 +Subject: [PATCH 15/44] drm/radeon: add uvd debugfs support + +Signed-off-by: Leo Liu <leo.liu@amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 1 + + drivers/gpu/drm/radeon/radeon_uvd.c | 37 +++++++++++++++++++++++++++++++++++ + 2 files changed, 38 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index a21b1d4..b212569 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -1549,6 +1549,7 @@ struct radeon_uvd { + struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; + unsigned img_size[RADEON_MAX_UVD_HANDLES]; + struct delayed_work idle_work; ++ bool status; + }; + + int radeon_uvd_init(struct radeon_device *rdev); +diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c +index 1d029cc..2b502b4 100644 +--- a/drivers/gpu/drm/radeon/radeon_uvd.c ++++ b/drivers/gpu/drm/radeon/radeon_uvd.c +@@ -53,6 +53,7 @@ MODULE_FIRMWARE(FIRMWARE_TAHITI); + MODULE_FIRMWARE(FIRMWARE_BONAIRE); + + static void radeon_uvd_idle_work_handler(struct work_struct *work); ++static int radeon_debugfs_uvd_init(struct radeon_device *rdev); + + int radeon_uvd_init(struct radeon_device *rdev) + { +@@ -142,6 +143,10 @@ int radeon_uvd_init(struct radeon_device *rdev) + return r; + } + ++ r = radeon_debugfs_uvd_init(rdev); ++ if (r) ++ dev_err(rdev->dev, "(%d) Register debugfs file for uvd failed\n", r); ++ + radeon_bo_unreserve(rdev->uvd.vcpu_bo); + + for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) { +@@ -785,6 +790,7 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work) + schedule_delayed_work(&rdev->uvd.idle_work, + msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS)); + } ++ rdev->uvd.status = false; + } + + void radeon_uvd_note_usage(struct radeon_device *rdev) +@@ -812,6 +818,7 @@ void radeon_uvd_note_usage(struct radeon_device *rdev) + } else { + radeon_set_uvd_clocks(rdev, 53300, 40000); + } ++ rdev->uvd.status = true; + } + } + +@@ -951,3 +958,33 @@ int radeon_uvd_send_upll_ctlreq(struct radeon_device *rdev, + + return 0; + } ++ ++/* ++ * Debugfs info ++ */ ++#if defined(CONFIG_DEBUG_FS) ++ ++static int radeon_debugfs_uvd_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct radeon_device *rdev = dev->dev_private; ++ ++ seq_printf(m, "UVD Status: %s\n", ((rdev->uvd.status) ? "Busy" : "Idle")); ++ ++ return 0; ++} ++ ++static struct drm_info_list radeon_uvd_info_list[] = { ++ {"radeon_uvd_info", radeon_debugfs_uvd_info, 0, NULL}, ++}; ++#endif ++ ++static int radeon_debugfs_uvd_init(struct radeon_device *rdev) ++{ ++#if defined(CONFIG_DEBUG_FS) ++ return radeon_debugfs_add_files(rdev, radeon_uvd_info_list, ARRAY_SIZE(radeon_uvd_info_list)); ++#else ++ return 0; ++#endif ++} +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0016-yocto-amd-drm-radeon-add-radeon_vm_bo_update-trace-point.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0016-yocto-amd-drm-radeon-add-radeon_vm_bo_update-trace-point.patch new file mode 100644 index 00000000..190b7b16 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0016-yocto-amd-drm-radeon-add-radeon_vm_bo_update-trace-point.patch @@ -0,0 +1,138 @@ +From b72be939a9ff7a33b0aa3ff3bd196ea016b8dce1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Mon, 25 Nov 2013 15:42:11 +0100 +Subject: [PATCH 16/44] drm/radeon: add radeon_vm_bo_update trace point +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Also rename the function to better reflect what it is doing. + +agd5f: fix argument size warning + +Signed-off-by: Christian König <christian.koenig@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 8 ++++---- + drivers/gpu/drm/radeon/radeon_cs.c | 4 ++-- + drivers/gpu/drm/radeon/radeon_gart.c | 14 ++++++++------ + drivers/gpu/drm/radeon/radeon_trace.h | 18 ++++++++++++++++++ + 4 files changed, 32 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index b212569..37e619c 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -2705,10 +2705,10 @@ void radeon_vm_fence(struct radeon_device *rdev, + struct radeon_vm *vm, + struct radeon_fence *fence); + uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr); +-int radeon_vm_bo_update_pte(struct radeon_device *rdev, +- struct radeon_vm *vm, +- struct radeon_bo *bo, +- struct ttm_mem_reg *mem); ++int radeon_vm_bo_update(struct radeon_device *rdev, ++ struct radeon_vm *vm, ++ struct radeon_bo *bo, ++ struct ttm_mem_reg *mem); + void radeon_vm_bo_invalidate(struct radeon_device *rdev, + struct radeon_bo *bo); + struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm, +diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c +index eb5cd94..83731ff 100644 +--- a/drivers/gpu/drm/radeon/radeon_cs.c ++++ b/drivers/gpu/drm/radeon/radeon_cs.c +@@ -407,13 +407,13 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, + struct radeon_bo *bo; + int r; + +- r = radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, &rdev->ring_tmp_bo.bo->tbo.mem); ++ r = radeon_vm_bo_update(rdev, vm, rdev->ring_tmp_bo.bo, &rdev->ring_tmp_bo.bo->tbo.mem); + if (r) { + return r; + } + list_for_each_entry(lobj, &parser->validated, tv.head) { + bo = lobj->bo; +- r = radeon_vm_bo_update_pte(parser->rdev, vm, bo, &bo->tbo.mem); ++ r = radeon_vm_bo_update(parser->rdev, vm, bo, &bo->tbo.mem); + if (r) { + return r; + } +diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c +index f7c0b64..33bd02e 100644 +--- a/drivers/gpu/drm/radeon/radeon_gart.c ++++ b/drivers/gpu/drm/radeon/radeon_gart.c +@@ -1071,7 +1071,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, + } + + /** +- * radeon_vm_bo_update_pte - map a bo into the vm page table ++ * radeon_vm_bo_update - map a bo into the vm page table + * + * @rdev: radeon_device pointer + * @vm: requested vm +@@ -1083,10 +1083,10 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, + * + * Object have to be reserved & global and local mutex must be locked! + */ +-int radeon_vm_bo_update_pte(struct radeon_device *rdev, +- struct radeon_vm *vm, +- struct radeon_bo *bo, +- struct ttm_mem_reg *mem) ++int radeon_vm_bo_update(struct radeon_device *rdev, ++ struct radeon_vm *vm, ++ struct radeon_bo *bo, ++ struct ttm_mem_reg *mem) + { + unsigned ridx = rdev->asic->vm.pt_ring_index; + struct radeon_ib ib; +@@ -1132,6 +1132,8 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, + bo_va->valid = false; + } + ++ trace_radeon_vm_bo_update(bo_va); ++ + nptes = radeon_bo_ngpu_pages(bo); + + /* assume two extra pdes in case the mapping overlaps the borders */ +@@ -1210,7 +1212,7 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, + mutex_lock(&rdev->vm_manager.lock); + mutex_lock(&bo_va->vm->mutex); + if (bo_va->soffset) { +- r = radeon_vm_bo_update_pte(rdev, bo_va->vm, bo_va->bo, NULL); ++ r = radeon_vm_bo_update(rdev, bo_va->vm, bo_va->bo, NULL); + } + mutex_unlock(&rdev->vm_manager.lock); + list_del(&bo_va->vm_list); +diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h +index 8c13aec..0473257 100644 +--- a/drivers/gpu/drm/radeon/radeon_trace.h ++++ b/drivers/gpu/drm/radeon/radeon_trace.h +@@ -62,6 +62,24 @@ TRACE_EVENT(radeon_vm_grab_id, + TP_printk("vmid=%u, ring=%u", __entry->vmid, __entry->ring) + ); + ++TRACE_EVENT(radeon_vm_bo_update, ++ TP_PROTO(struct radeon_bo_va *bo_va), ++ TP_ARGS(bo_va), ++ TP_STRUCT__entry( ++ __field(u64, soffset) ++ __field(u64, eoffset) ++ __field(u32, flags) ++ ), ++ ++ TP_fast_assign( ++ __entry->soffset = bo_va->soffset; ++ __entry->eoffset = bo_va->eoffset; ++ __entry->flags = bo_va->flags; ++ ), ++ TP_printk("soffs=%010llx, eoffs=%010llx, flags=%08x", ++ __entry->soffset, __entry->eoffset, __entry->flags) ++); ++ + TRACE_EVENT(radeon_vm_set_page, + TP_PROTO(uint64_t pe, uint64_t addr, unsigned count, + uint32_t incr, uint32_t flags), +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0017-yocto-amd-drm-radeon-drop-CP-page-table-updates-cleanup-v2.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0017-yocto-amd-drm-radeon-drop-CP-page-table-updates-cleanup-v2.patch new file mode 100644 index 00000000..0f88bc76 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0017-yocto-amd-drm-radeon-drop-CP-page-table-updates-cleanup-v2.patch @@ -0,0 +1,676 @@ +From 6a98674d6cb42c43b6a5e9dd2719b52a50b9e489 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Wed, 30 Oct 2013 11:51:09 -0400 +Subject: [PATCH 17/44] drm/radeon: drop CP page table updates & cleanup v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The DMA ring seems to be stable now. + +v2: remove pt_ring_index as well + +Signed-off-by: Christian König <christian.koenig@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/cik.c | 56 ------------------------- + drivers/gpu/drm/radeon/cik_sdma.c | 21 ++++------ + drivers/gpu/drm/radeon/ni.c | 76 ---------------------------------- + drivers/gpu/drm/radeon/ni_dma.c | 18 ++++---- + drivers/gpu/drm/radeon/radeon.h | 8 +++- + drivers/gpu/drm/radeon/radeon_asic.c | 15 +++---- + drivers/gpu/drm/radeon/radeon_asic.h | 31 +++++++------- + drivers/gpu/drm/radeon/radeon_gart.c | 29 ++++++++++--- + drivers/gpu/drm/radeon/si.c | 60 --------------------------- + drivers/gpu/drm/radeon/si_dma.c | 21 ++++------ + 10 files changed, 73 insertions(+), 262 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index 0608446..d7e86ef3 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -4825,62 +4825,6 @@ void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) + } + } + +-/** +- * cik_vm_set_page - update the page tables using sDMA +- * +- * @rdev: radeon_device pointer +- * @ib: indirect buffer to fill with commands +- * @pe: addr of the page entry +- * @addr: dst addr to write into pe +- * @count: number of page entries to update +- * @incr: increase next addr by incr bytes +- * @flags: access flags +- * +- * Update the page tables using CP or sDMA (CIK). +- */ +-void cik_vm_set_page(struct radeon_device *rdev, +- struct radeon_ib *ib, +- uint64_t pe, +- uint64_t addr, unsigned count, +- uint32_t incr, uint32_t flags) +-{ +- uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); +- uint64_t value; +- unsigned ndw; +- +- if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) { +- /* CP */ +- while (count) { +- ndw = 2 + count * 2; +- if (ndw > 0x3FFE) +- ndw = 0x3FFE; +- +- ib->ptr[ib->length_dw++] = PACKET3(PACKET3_WRITE_DATA, ndw); +- ib->ptr[ib->length_dw++] = (WRITE_DATA_ENGINE_SEL(0) | +- WRITE_DATA_DST_SEL(1)); +- ib->ptr[ib->length_dw++] = pe; +- ib->ptr[ib->length_dw++] = upper_32_bits(pe); +- for (; ndw > 2; ndw -= 2, --count, pe += 8) { +- if (flags & RADEON_VM_PAGE_SYSTEM) { +- value = radeon_vm_map_gart(rdev, addr); +- value &= 0xFFFFFFFFFFFFF000ULL; +- } else if (flags & RADEON_VM_PAGE_VALID) { +- value = addr; +- } else { +- value = 0; +- } +- addr += incr; +- value |= r600_flags; +- ib->ptr[ib->length_dw++] = value; +- ib->ptr[ib->length_dw++] = upper_32_bits(value); +- } +- } +- } else { +- /* DMA */ +- cik_sdma_vm_set_page(rdev, ib, pe, addr, count, incr, flags); +- } +-} +- + /* + * RLC + * The RLC is a multi-purpose microengine that handles a +diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c +index ace0bc6..8517a62 100644 +--- a/drivers/gpu/drm/radeon/cik_sdma.c ++++ b/drivers/gpu/drm/radeon/cik_sdma.c +@@ -646,13 +646,12 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, + uint64_t addr, unsigned count, + uint32_t incr, uint32_t flags) + { +- uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); + uint64_t value; + unsigned ndw; + +- trace_radeon_vm_set_page(pe, addr, count, incr, r600_flags); ++ trace_radeon_vm_set_page(pe, addr, count, incr, flags); + +- if (flags & RADEON_VM_PAGE_SYSTEM) { ++ if (flags & R600_PTE_SYSTEM) { + while (count) { + ndw = count * 2; + if (ndw > 0xFFFFE) +@@ -664,16 +663,10 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, + ib->ptr[ib->length_dw++] = upper_32_bits(pe); + ib->ptr[ib->length_dw++] = ndw; + for (; ndw > 0; ndw -= 2, --count, pe += 8) { +- if (flags & RADEON_VM_PAGE_SYSTEM) { +- value = radeon_vm_map_gart(rdev, addr); +- value &= 0xFFFFFFFFFFFFF000ULL; +- } else if (flags & RADEON_VM_PAGE_VALID) { +- value = addr; +- } else { +- value = 0; +- } ++ value = radeon_vm_map_gart(rdev, addr); ++ value &= 0xFFFFFFFFFFFFF000ULL; + addr += incr; +- value |= r600_flags; ++ value |= flags; + ib->ptr[ib->length_dw++] = value; + ib->ptr[ib->length_dw++] = upper_32_bits(value); + } +@@ -684,7 +677,7 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, + if (ndw > 0x7FFFF) + ndw = 0x7FFFF; + +- if (flags & RADEON_VM_PAGE_VALID) ++ if (flags & R600_PTE_VALID) + value = addr; + else + value = 0; +@@ -692,7 +685,7 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, + ib->ptr[ib->length_dw++] = SDMA_PACKET(SDMA_OPCODE_GENERATE_PTE_PDE, 0, 0); + ib->ptr[ib->length_dw++] = pe; /* dst addr */ + ib->ptr[ib->length_dw++] = upper_32_bits(pe); +- ib->ptr[ib->length_dw++] = r600_flags; /* mask */ ++ ib->ptr[ib->length_dw++] = flags; /* mask */ + ib->ptr[ib->length_dw++] = 0; + ib->ptr[ib->length_dw++] = value; /* value */ + ib->ptr[ib->length_dw++] = upper_32_bits(value); +diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +index 954eb9a..f59a9e9 100644 +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -174,11 +174,6 @@ extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev); + extern void evergreen_program_aspm(struct radeon_device *rdev); + extern void sumo_rlc_fini(struct radeon_device *rdev); + extern int sumo_rlc_init(struct radeon_device *rdev); +-extern void cayman_dma_vm_set_page(struct radeon_device *rdev, +- struct radeon_ib *ib, +- uint64_t pe, +- uint64_t addr, unsigned count, +- uint32_t incr, uint32_t flags); + + /* Firmware Names */ + MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); +@@ -2412,77 +2407,6 @@ void cayman_vm_decode_fault(struct radeon_device *rdev, + block, mc_id); + } + +-#define R600_ENTRY_VALID (1 << 0) +-#define R600_PTE_SYSTEM (1 << 1) +-#define R600_PTE_SNOOPED (1 << 2) +-#define R600_PTE_READABLE (1 << 5) +-#define R600_PTE_WRITEABLE (1 << 6) +- +-uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags) +-{ +- uint32_t r600_flags = 0; +- r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0; +- r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; +- r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; +- if (flags & RADEON_VM_PAGE_SYSTEM) { +- r600_flags |= R600_PTE_SYSTEM; +- r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0; +- } +- return r600_flags; +-} +- +-/** +- * cayman_vm_set_page - update the page tables using the CP +- * +- * @rdev: radeon_device pointer +- * @ib: indirect buffer to fill with commands +- * @pe: addr of the page entry +- * @addr: dst addr to write into pe +- * @count: number of page entries to update +- * @incr: increase next addr by incr bytes +- * @flags: access flags +- * +- * Update the page tables using the CP (cayman/TN). +- */ +-void cayman_vm_set_page(struct radeon_device *rdev, +- struct radeon_ib *ib, +- uint64_t pe, +- uint64_t addr, unsigned count, +- uint32_t incr, uint32_t flags) +-{ +- uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); +- uint64_t value; +- unsigned ndw; +- +- if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) { +- while (count) { +- ndw = 1 + count * 2; +- if (ndw > 0x3FFF) +- ndw = 0x3FFF; +- +- ib->ptr[ib->length_dw++] = PACKET3(PACKET3_ME_WRITE, ndw); +- ib->ptr[ib->length_dw++] = pe; +- ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; +- for (; ndw > 1; ndw -= 2, --count, pe += 8) { +- if (flags & RADEON_VM_PAGE_SYSTEM) { +- value = radeon_vm_map_gart(rdev, addr); +- value &= 0xFFFFFFFFFFFFF000ULL; +- } else if (flags & RADEON_VM_PAGE_VALID) { +- value = addr; +- } else { +- value = 0; +- } +- addr += incr; +- value |= r600_flags; +- ib->ptr[ib->length_dw++] = value; +- ib->ptr[ib->length_dw++] = upper_32_bits(value); +- } +- } +- } else { +- cayman_dma_vm_set_page(rdev, ib, pe, addr, count, incr, flags); +- } +-} +- + /** + * cayman_vm_flush - vm flush using the CP + * +diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c +index e9cfe8a..bdeb65e 100644 +--- a/drivers/gpu/drm/radeon/ni_dma.c ++++ b/drivers/gpu/drm/radeon/ni_dma.c +@@ -246,8 +246,7 @@ bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) + * @addr: dst addr to write into pe + * @count: number of page entries to update + * @incr: increase next addr by incr bytes +- * @flags: access flags +- * @r600_flags: hw access flags ++ * @flags: hw access flags + * + * Update the page tables using the DMA (cayman/TN). + */ +@@ -257,13 +256,12 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, + uint64_t addr, unsigned count, + uint32_t incr, uint32_t flags) + { +- uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); + uint64_t value; + unsigned ndw; + +- trace_radeon_vm_set_page(pe, addr, count, incr, r600_flags); ++ trace_radeon_vm_set_page(pe, addr, count, incr, flags); + +- if ((flags & RADEON_VM_PAGE_SYSTEM) || (count == 1)) { ++ if ((flags & R600_PTE_SYSTEM) || (count == 1)) { + while (count) { + ndw = count * 2; + if (ndw > 0xFFFFE) +@@ -274,16 +272,16 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, + ib->ptr[ib->length_dw++] = pe; + ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; + for (; ndw > 0; ndw -= 2, --count, pe += 8) { +- if (flags & RADEON_VM_PAGE_SYSTEM) { ++ if (flags & R600_PTE_SYSTEM) { + value = radeon_vm_map_gart(rdev, addr); + value &= 0xFFFFFFFFFFFFF000ULL; +- } else if (flags & RADEON_VM_PAGE_VALID) { ++ } else if (flags & R600_PTE_VALID) { + value = addr; + } else { + value = 0; + } + addr += incr; +- value |= r600_flags; ++ value |= flags; + ib->ptr[ib->length_dw++] = value; + ib->ptr[ib->length_dw++] = upper_32_bits(value); + } +@@ -294,7 +292,7 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, + if (ndw > 0xFFFFE) + ndw = 0xFFFFE; + +- if (flags & RADEON_VM_PAGE_VALID) ++ if (flags & R600_PTE_VALID) + value = addr; + else + value = 0; +@@ -302,7 +300,7 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, + ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw); + ib->ptr[ib->length_dw++] = pe; /* dst addr */ + ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; +- ib->ptr[ib->length_dw++] = r600_flags; /* mask */ ++ ib->ptr[ib->length_dw++] = flags; /* mask */ + ib->ptr[ib->length_dw++] = 0; + ib->ptr[ib->length_dw++] = value; /* value */ + ib->ptr[ib->length_dw++] = upper_32_bits(value); +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 37e619c..b987f01 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -840,6 +840,12 @@ struct radeon_mec { + #define RADEON_VM_PTB_ALIGN_MASK (RADEON_VM_PTB_ALIGN_SIZE - 1) + #define RADEON_VM_PTB_ALIGN(a) (((a) + RADEON_VM_PTB_ALIGN_MASK) & ~RADEON_VM_PTB_ALIGN_MASK) + ++#define R600_PTE_VALID (1 << 0) ++#define R600_PTE_SYSTEM (1 << 1) ++#define R600_PTE_SNOOPED (1 << 2) ++#define R600_PTE_READABLE (1 << 5) ++#define R600_PTE_WRITEABLE (1 << 6) ++ + struct radeon_vm { + struct list_head list; + struct list_head va; +@@ -1685,8 +1691,6 @@ struct radeon_asic { + struct { + int (*init)(struct radeon_device *rdev); + void (*fini)(struct radeon_device *rdev); +- +- u32 pt_ring_index; + void (*set_page)(struct radeon_device *rdev, + struct radeon_ib *ib, + uint64_t pe, +diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c +index 5720e66..123adfe 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.c ++++ b/drivers/gpu/drm/radeon/radeon_asic.c +@@ -1622,8 +1622,7 @@ static struct radeon_asic cayman_asic = { + .vm = { + .init = &cayman_vm_init, + .fini = &cayman_vm_fini, +- .pt_ring_index = R600_RING_TYPE_DMA_INDEX, +- .set_page = &cayman_vm_set_page, ++ .set_page = &cayman_dma_vm_set_page, + }, + .ring = { + [RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring, +@@ -1723,8 +1722,7 @@ static struct radeon_asic trinity_asic = { + .vm = { + .init = &cayman_vm_init, + .fini = &cayman_vm_fini, +- .pt_ring_index = R600_RING_TYPE_DMA_INDEX, +- .set_page = &cayman_vm_set_page, ++ .set_page = &cayman_dma_vm_set_page, + }, + .ring = { + [RADEON_RING_TYPE_GFX_INDEX] = &cayman_gfx_ring, +@@ -1854,8 +1852,7 @@ static struct radeon_asic si_asic = { + .vm = { + .init = &si_vm_init, + .fini = &si_vm_fini, +- .pt_ring_index = R600_RING_TYPE_DMA_INDEX, +- .set_page = &si_vm_set_page, ++ .set_page = &si_dma_vm_set_page, + }, + .ring = { + [RADEON_RING_TYPE_GFX_INDEX] = &si_gfx_ring, +@@ -2000,8 +1997,7 @@ static struct radeon_asic ci_asic = { + .vm = { + .init = &cik_vm_init, + .fini = &cik_vm_fini, +- .pt_ring_index = R600_RING_TYPE_DMA_INDEX, +- .set_page = &cik_vm_set_page, ++ .set_page = &cik_sdma_vm_set_page, + }, + .ring = { + [RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring, +@@ -2102,8 +2098,7 @@ static struct radeon_asic kv_asic = { + .vm = { + .init = &cik_vm_init, + .fini = &cik_vm_fini, +- .pt_ring_index = R600_RING_TYPE_DMA_INDEX, +- .set_page = &cik_vm_set_page, ++ .set_page = &cik_sdma_vm_set_page, + }, + .ring = { + [RADEON_RING_TYPE_GFX_INDEX] = &ci_gfx_ring, +diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h +index 8588670..8939cb3 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.h ++++ b/drivers/gpu/drm/radeon/radeon_asic.h +@@ -577,17 +577,18 @@ int cayman_vm_init(struct radeon_device *rdev); + void cayman_vm_fini(struct radeon_device *rdev); + void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); + uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); +-void cayman_vm_set_page(struct radeon_device *rdev, +- struct radeon_ib *ib, +- uint64_t pe, +- uint64_t addr, unsigned count, +- uint32_t incr, uint32_t flags); + int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); + int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); + void cayman_dma_ring_ib_execute(struct radeon_device *rdev, + struct radeon_ib *ib); + bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); + bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); ++void cayman_dma_vm_set_page(struct radeon_device *rdev, ++ struct radeon_ib *ib, ++ uint64_t pe, ++ uint64_t addr, unsigned count, ++ uint32_t incr, uint32_t flags); ++ + void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); + + int ni_dpm_init(struct radeon_device *rdev); +@@ -649,17 +650,17 @@ int si_irq_set(struct radeon_device *rdev); + int si_irq_process(struct radeon_device *rdev); + int si_vm_init(struct radeon_device *rdev); + void si_vm_fini(struct radeon_device *rdev); +-void si_vm_set_page(struct radeon_device *rdev, +- struct radeon_ib *ib, +- uint64_t pe, +- uint64_t addr, unsigned count, +- uint32_t incr, uint32_t flags); + void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); + int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); + int si_copy_dma(struct radeon_device *rdev, + uint64_t src_offset, uint64_t dst_offset, + unsigned num_gpu_pages, + struct radeon_fence **fence); ++void si_dma_vm_set_page(struct radeon_device *rdev, ++ struct radeon_ib *ib, ++ uint64_t pe, ++ uint64_t addr, unsigned count, ++ uint32_t incr, uint32_t flags); + void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); + u32 si_get_xclk(struct radeon_device *rdev); + uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev); +@@ -727,11 +728,11 @@ int cik_irq_process(struct radeon_device *rdev); + int cik_vm_init(struct radeon_device *rdev); + void cik_vm_fini(struct radeon_device *rdev); + void cik_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); +-void cik_vm_set_page(struct radeon_device *rdev, +- struct radeon_ib *ib, +- uint64_t pe, +- uint64_t addr, unsigned count, +- uint32_t incr, uint32_t flags); ++void cik_sdma_vm_set_page(struct radeon_device *rdev, ++ struct radeon_ib *ib, ++ uint64_t pe, ++ uint64_t addr, unsigned count, ++ uint32_t incr, uint32_t flags); + void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); + int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); + u32 cik_compute_ring_get_rptr(struct radeon_device *rdev, +diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c +index 33bd02e..9ceabdf 100644 +--- a/drivers/gpu/drm/radeon/radeon_gart.c ++++ b/drivers/gpu/drm/radeon/radeon_gart.c +@@ -920,6 +920,26 @@ uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr) + } + + /** ++ * radeon_vm_page_flags - translate page flags to what the hw uses ++ * ++ * @flags: flags comming from userspace ++ * ++ * Translate the flags the userspace ABI uses to hw flags. ++ */ ++static uint32_t radeon_vm_page_flags(uint32_t flags) ++{ ++ uint32_t hw_flags = 0; ++ hw_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_PTE_VALID : 0; ++ hw_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; ++ hw_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; ++ if (flags & RADEON_VM_PAGE_SYSTEM) { ++ hw_flags |= R600_PTE_SYSTEM; ++ hw_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0; ++ } ++ return hw_flags; ++} ++ ++/** + * radeon_vm_update_pdes - make sure that page directory is valid + * + * @rdev: radeon_device pointer +@@ -980,7 +1000,7 @@ retry: + if (count) { + radeon_asic_vm_set_page(rdev, ib, last_pde, + last_pt, count, incr, +- RADEON_VM_PAGE_VALID); ++ R600_PTE_VALID); + } + + count = 1; +@@ -993,7 +1013,7 @@ retry: + + if (count) { + radeon_asic_vm_set_page(rdev, ib, last_pde, last_pt, count, +- incr, RADEON_VM_PAGE_VALID); ++ incr, R600_PTE_VALID); + + } + +@@ -1088,7 +1108,6 @@ int radeon_vm_bo_update(struct radeon_device *rdev, + struct radeon_bo *bo, + struct ttm_mem_reg *mem) + { +- unsigned ridx = rdev->asic->vm.pt_ring_index; + struct radeon_ib ib; + struct radeon_bo_va *bo_va; + unsigned nptes, npdes, ndw; +@@ -1163,7 +1182,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev, + if (ndw > 0xfffff) + return -ENOMEM; + +- r = radeon_ib_get(rdev, ridx, &ib, NULL, ndw * 4); ++ r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, ndw * 4); + if (r) + return r; + ib.length_dw = 0; +@@ -1175,7 +1194,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev, + } + + radeon_vm_update_ptes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset, +- addr, bo_va->flags); ++ addr, radeon_vm_page_flags(bo_va->flags)); + + radeon_semaphore_sync_to(ib.semaphore, vm->fence); + r = radeon_ib_schedule(rdev, &ib, NULL); +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index 37acf93..0334f3e 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -78,11 +78,6 @@ extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_ + extern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev); + extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); + extern bool evergreen_is_display_hung(struct radeon_device *rdev); +-extern void si_dma_vm_set_page(struct radeon_device *rdev, +- struct radeon_ib *ib, +- uint64_t pe, +- uint64_t addr, unsigned count, +- uint32_t incr, uint32_t flags); + static void si_enable_gui_idle_interrupt(struct radeon_device *rdev, + bool enable); + static void si_fini_pg(struct radeon_device *rdev); +@@ -4682,61 +4677,6 @@ static void si_vm_decode_fault(struct radeon_device *rdev, + block, mc_id); + } + +-/** +- * si_vm_set_page - update the page tables using the CP +- * +- * @rdev: radeon_device pointer +- * @ib: indirect buffer to fill with commands +- * @pe: addr of the page entry +- * @addr: dst addr to write into pe +- * @count: number of page entries to update +- * @incr: increase next addr by incr bytes +- * @flags: access flags +- * +- * Update the page tables using the CP (SI). +- */ +-void si_vm_set_page(struct radeon_device *rdev, +- struct radeon_ib *ib, +- uint64_t pe, +- uint64_t addr, unsigned count, +- uint32_t incr, uint32_t flags) +-{ +- uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); +- uint64_t value; +- unsigned ndw; +- +- if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) { +- while (count) { +- ndw = 2 + count * 2; +- if (ndw > 0x3FFE) +- ndw = 0x3FFE; +- +- ib->ptr[ib->length_dw++] = PACKET3(PACKET3_WRITE_DATA, ndw); +- ib->ptr[ib->length_dw++] = (WRITE_DATA_ENGINE_SEL(0) | +- WRITE_DATA_DST_SEL(1)); +- ib->ptr[ib->length_dw++] = pe; +- ib->ptr[ib->length_dw++] = upper_32_bits(pe); +- for (; ndw > 2; ndw -= 2, --count, pe += 8) { +- if (flags & RADEON_VM_PAGE_SYSTEM) { +- value = radeon_vm_map_gart(rdev, addr); +- value &= 0xFFFFFFFFFFFFF000ULL; +- } else if (flags & RADEON_VM_PAGE_VALID) { +- value = addr; +- } else { +- value = 0; +- } +- addr += incr; +- value |= r600_flags; +- ib->ptr[ib->length_dw++] = value; +- ib->ptr[ib->length_dw++] = upper_32_bits(value); +- } +- } +- } else { +- /* DMA */ +- si_dma_vm_set_page(rdev, ib, pe, addr, count, incr, flags); +- } +-} +- + void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) + { + struct radeon_ring *ring = &rdev->ring[ridx]; +diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c +index 97af34c..59be2cf 100644 +--- a/drivers/gpu/drm/radeon/si_dma.c ++++ b/drivers/gpu/drm/radeon/si_dma.c +@@ -76,13 +76,12 @@ void si_dma_vm_set_page(struct radeon_device *rdev, + uint64_t addr, unsigned count, + uint32_t incr, uint32_t flags) + { +- uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); + uint64_t value; + unsigned ndw; + +- trace_radeon_vm_set_page(pe, addr, count, incr, r600_flags); ++ trace_radeon_vm_set_page(pe, addr, count, incr, flags); + +- if (flags & RADEON_VM_PAGE_SYSTEM) { ++ if (flags & R600_PTE_SYSTEM) { + while (count) { + ndw = count * 2; + if (ndw > 0xFFFFE) +@@ -93,16 +92,10 @@ void si_dma_vm_set_page(struct radeon_device *rdev, + ib->ptr[ib->length_dw++] = pe; + ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; + for (; ndw > 0; ndw -= 2, --count, pe += 8) { +- if (flags & RADEON_VM_PAGE_SYSTEM) { +- value = radeon_vm_map_gart(rdev, addr); +- value &= 0xFFFFFFFFFFFFF000ULL; +- } else if (flags & RADEON_VM_PAGE_VALID) { +- value = addr; +- } else { +- value = 0; +- } ++ value = radeon_vm_map_gart(rdev, addr); ++ value &= 0xFFFFFFFFFFFFF000ULL; + addr += incr; +- value |= r600_flags; ++ value |= flags; + ib->ptr[ib->length_dw++] = value; + ib->ptr[ib->length_dw++] = upper_32_bits(value); + } +@@ -113,7 +106,7 @@ void si_dma_vm_set_page(struct radeon_device *rdev, + if (ndw > 0xFFFFE) + ndw = 0xFFFFE; + +- if (flags & RADEON_VM_PAGE_VALID) ++ if (flags & R600_PTE_VALID) + value = addr; + else + value = 0; +@@ -121,7 +114,7 @@ void si_dma_vm_set_page(struct radeon_device *rdev, + ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw); + ib->ptr[ib->length_dw++] = pe; /* dst addr */ + ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; +- ib->ptr[ib->length_dw++] = r600_flags; /* mask */ ++ ib->ptr[ib->length_dw++] = flags; /* mask */ + ib->ptr[ib->length_dw++] = 0; + ib->ptr[ib->length_dw++] = value; /* value */ + ib->ptr[ib->length_dw++] = upper_32_bits(value); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0018-yocto-amd-drm-radeon-add-large-PTE-support-for-NI-SI-and-CIK-v.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0018-yocto-amd-drm-radeon-add-large-PTE-support-for-NI-SI-and-CIK-v.patch new file mode 100644 index 00000000..6498c071 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0018-yocto-amd-drm-radeon-add-large-PTE-support-for-NI-SI-and-CIK-v.patch @@ -0,0 +1,237 @@ +From a2bc39a6394bb8e11060df3da33d603a66ccf9f6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Fri, 25 Oct 2013 18:07:55 +0200 +Subject: [PATCH 18/44] drm/radeon: add large PTE support for NI, SI and CIK + v3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch implements support for VRAM page table entry compression. +PTE construction is enhanced to identify physically contiguous page +ranges and mark them in the PTE fragment field. L1 TLB and L2 cache +support is enabled for 64KB (SI/CIK) and 256KB (NI) PTE fragments, +significantly improving TLB utilization for VRAM allocations. + +Linear store bandwidth is improved from 60GB/s to 125GB/s on Pitcairn. +Unigine Heaven 3.0 sees an average improvement from 24.7 to 27.7 FPS +on default settings at 1920x1200 resolution with vsync disabled. + +See main comment in radeon_gart.c gives a technical description. + +v2 (chk): rebased and simplified. +v3 (chk): add missing hw setup + +Signed-off-by: Jay Cornwall <jay@jcornwall.me> +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/cik.c | 4 +- + drivers/gpu/drm/radeon/ni.c | 2 + + drivers/gpu/drm/radeon/radeon.h | 5 ++ + drivers/gpu/drm/radeon/radeon_gart.c | 91 +++++++++++++++++++++++++++++++--- + drivers/gpu/drm/radeon/si.c | 5 +- + 5 files changed, 98 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index d7e86ef3..27fa479 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -4522,6 +4522,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) + WREG32(MC_VM_MX_L1_TLB_CNTL, + (0xA << 7) | + ENABLE_L1_TLB | ++ ENABLE_L1_FRAGMENT_PROCESSING | + SYSTEM_ACCESS_MODE_NOT_IN_SYS | + ENABLE_ADVANCED_DRIVER_MODEL | + SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); +@@ -4534,7 +4535,8 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) + CONTEXT1_IDENTITY_ACCESS_MODE(1)); + WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE); + WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | +- L2_CACHE_BIGK_FRAGMENT_SIZE(6)); ++ BANK_SELECT(4) | ++ L2_CACHE_BIGK_FRAGMENT_SIZE(4)); + /* setup context0 */ + WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); + WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); +diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +index f59a9e9..9291982 100644 +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -1227,12 +1227,14 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) + SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); + /* Setup L2 cache */ + WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ++ ENABLE_L2_FRAGMENT_PROCESSING | + ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | + ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | + EFFECTIVE_L2_QUEUE_SIZE(7) | + CONTEXT1_IDENTITY_ACCESS_MODE(1)); + WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE); + WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | ++ BANK_SELECT(6) | + L2_CACHE_BIGK_FRAGMENT_SIZE(6)); + /* setup context0 */ + WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index b987f01..06b3375 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -846,6 +846,11 @@ struct radeon_mec { + #define R600_PTE_READABLE (1 << 5) + #define R600_PTE_WRITEABLE (1 << 6) + ++/* PTE (Page Table Entry) fragment field for different page sizes */ ++#define R600_PTE_FRAG_4KB (0 << 7) ++#define R600_PTE_FRAG_64KB (4 << 7) ++#define R600_PTE_FRAG_256KB (6 << 7) ++ + struct radeon_vm { + struct list_head list; + struct list_head va; +diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c +index 9ceabdf..f960ce6 100644 +--- a/drivers/gpu/drm/radeon/radeon_gart.c ++++ b/drivers/gpu/drm/radeon/radeon_gart.c +@@ -1021,6 +1021,84 @@ retry: + } + + /** ++ * radeon_vm_frag_ptes - add fragment information to PTEs ++ * ++ * @rdev: radeon_device pointer ++ * @ib: IB for the update ++ * @pe_start: first PTE to handle ++ * @pe_end: last PTE to handle ++ * @addr: addr those PTEs should point to ++ * @flags: hw mapping flags ++ * ++ * Global and local mutex must be locked! ++ */ ++static void radeon_vm_frag_ptes(struct radeon_device *rdev, ++ struct radeon_ib *ib, ++ uint64_t pe_start, uint64_t pe_end, ++ uint64_t addr, uint32_t flags) ++{ ++ /** ++ * The MC L1 TLB supports variable sized pages, based on a fragment ++ * field in the PTE. When this field is set to a non-zero value, page ++ * granularity is increased from 4KB to (1 << (12 + frag)). The PTE ++ * flags are considered valid for all PTEs within the fragment range ++ * and corresponding mappings are assumed to be physically contiguous. ++ * ++ * The L1 TLB can store a single PTE for the whole fragment, ++ * significantly increasing the space available for translation ++ * caching. This leads to large improvements in throughput when the ++ * TLB is under pressure. ++ * ++ * The L2 cache distributes small and large fragments into two ++ * asymmetric partitions. The large fragment cache is significantly ++ * larger. Thus, we try to use large fragments wherever possible. ++ * Userspace can support this by aligning virtual base address and ++ * allocation size to the fragment size. ++ */ ++ ++ /* NI is optimized for 256KB fragments, SI and newer for 64KB */ ++ uint64_t frag_flags = rdev->family == CHIP_CAYMAN ? ++ R600_PTE_FRAG_256KB : R600_PTE_FRAG_64KB; ++ uint64_t frag_align = rdev->family == CHIP_CAYMAN ? 0x200 : 0x80; ++ ++ uint64_t frag_start = ALIGN(pe_start, frag_align); ++ uint64_t frag_end = pe_end & ~(frag_align - 1); ++ ++ unsigned count; ++ ++ /* system pages are non continuously */ ++ if ((flags & R600_PTE_SYSTEM) || !(flags & R600_PTE_VALID) || ++ (frag_start >= frag_end)) { ++ ++ count = (pe_end - pe_start) / 8; ++ radeon_asic_vm_set_page(rdev, ib, pe_start, addr, count, ++ RADEON_GPU_PAGE_SIZE, flags); ++ return; ++ } ++ ++ /* handle the 4K area at the beginning */ ++ if (pe_start != frag_start) { ++ count = (frag_start - pe_start) / 8; ++ radeon_asic_vm_set_page(rdev, ib, pe_start, addr, count, ++ RADEON_GPU_PAGE_SIZE, flags); ++ addr += RADEON_GPU_PAGE_SIZE * count; ++ } ++ ++ /* handle the area in the middle */ ++ count = (frag_end - frag_start) / 8; ++ radeon_asic_vm_set_page(rdev, ib, frag_start, addr, count, ++ RADEON_GPU_PAGE_SIZE, flags | frag_flags); ++ ++ /* handle the 4K area at the end */ ++ if (frag_end != pe_end) { ++ addr += RADEON_GPU_PAGE_SIZE * count; ++ count = (pe_end - frag_end) / 8; ++ radeon_asic_vm_set_page(rdev, ib, frag_end, addr, count, ++ RADEON_GPU_PAGE_SIZE, flags); ++ } ++} ++ ++/** + * radeon_vm_update_ptes - make sure that page tables are valid + * + * @rdev: radeon_device pointer +@@ -1066,10 +1144,9 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, + if ((last_pte + 8 * count) != pte) { + + if (count) { +- radeon_asic_vm_set_page(rdev, ib, last_pte, +- last_dst, count, +- RADEON_GPU_PAGE_SIZE, +- flags); ++ radeon_vm_frag_ptes(rdev, ib, last_pte, ++ last_pte + 8 * count, ++ last_dst, flags); + } + + count = nptes; +@@ -1084,9 +1161,9 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, + } + + if (count) { +- radeon_asic_vm_set_page(rdev, ib, last_pte, +- last_dst, count, +- RADEON_GPU_PAGE_SIZE, flags); ++ radeon_vm_frag_ptes(rdev, ib, last_pte, ++ last_pte + 8 * count, ++ last_dst, flags); + } + } + +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index 0334f3e..d9173ef 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -3928,18 +3928,21 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) + WREG32(MC_VM_MX_L1_TLB_CNTL, + (0xA << 7) | + ENABLE_L1_TLB | ++ ENABLE_L1_FRAGMENT_PROCESSING | + SYSTEM_ACCESS_MODE_NOT_IN_SYS | + ENABLE_ADVANCED_DRIVER_MODEL | + SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); + /* Setup L2 cache */ + WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ++ ENABLE_L2_FRAGMENT_PROCESSING | + ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | + ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | + EFFECTIVE_L2_QUEUE_SIZE(7) | + CONTEXT1_IDENTITY_ACCESS_MODE(1)); + WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE); + WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | +- L2_CACHE_BIGK_FRAGMENT_SIZE(0)); ++ BANK_SELECT(4) | ++ L2_CACHE_BIGK_FRAGMENT_SIZE(4)); + /* setup context0 */ + WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); + WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0019-yocto-amd-drm-radeon-add-proper-support-for-RADEON_VM_BLOCK_SI.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0019-yocto-amd-drm-radeon-add-proper-support-for-RADEON_VM_BLOCK_SI.patch new file mode 100644 index 00000000..8061d7ba --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0019-yocto-amd-drm-radeon-add-proper-support-for-RADEON_VM_BLOCK_SI.patch @@ -0,0 +1,133 @@ +From 7ef7e2da03959058588c4f0bc68e32b1bf17e1d9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Tue, 29 Oct 2013 09:30:16 +0100 +Subject: [PATCH 19/44] drm/radeon: add proper support for + RADEON_VM_BLOCK_SIZE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch makes it possible to decide how many address +bits are spend on the page directory vs the page tables. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/cik.c | 1 + + drivers/gpu/drm/radeon/cikd.h | 1 + + drivers/gpu/drm/radeon/ni.c | 1 + + drivers/gpu/drm/radeon/nid.h | 1 + + drivers/gpu/drm/radeon/radeon.h | 2 +- + drivers/gpu/drm/radeon/radeon_gart.c | 3 ++- + drivers/gpu/drm/radeon/si.c | 1 + + drivers/gpu/drm/radeon/sid.h | 1 + + 8 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index 27fa479..cd5f85e 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -4572,6 +4572,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev) + (u32)(rdev->dummy_page.addr >> 12)); + WREG32(VM_CONTEXT1_CNTL2, 4); + WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) | ++ PAGE_TABLE_BLOCK_SIZE(RADEON_VM_BLOCK_SIZE - 9) | + RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT | + RANGE_PROTECTION_FAULT_ENABLE_DEFAULT | + DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT | +diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h +index 203d2a0..7a0a0d2 100644 +--- a/drivers/gpu/drm/radeon/cikd.h ++++ b/drivers/gpu/drm/radeon/cikd.h +@@ -474,6 +474,7 @@ + #define READ_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 16) + #define WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 18) + #define WRITE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 19) ++#define PAGE_TABLE_BLOCK_SIZE(x) (((x) & 0xF) << 24) + #define VM_CONTEXT1_CNTL 0x1414 + #define VM_CONTEXT0_CNTL2 0x1430 + #define VM_CONTEXT1_CNTL2 0x1434 +diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +index 9291982..ce87221 100644 +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -1267,6 +1267,7 @@ static int cayman_pcie_gart_enable(struct radeon_device *rdev) + (u32)(rdev->dummy_page.addr >> 12)); + WREG32(VM_CONTEXT1_CNTL2, 4); + WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) | ++ PAGE_TABLE_BLOCK_SIZE(RADEON_VM_BLOCK_SIZE - 9) | + RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT | + RANGE_PROTECTION_FAULT_ENABLE_DEFAULT | + DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT | +diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h +index 22421bc..ef7ba2d 100644 +--- a/drivers/gpu/drm/radeon/nid.h ++++ b/drivers/gpu/drm/radeon/nid.h +@@ -128,6 +128,7 @@ + #define READ_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 16) + #define WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 18) + #define WRITE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 19) ++#define PAGE_TABLE_BLOCK_SIZE(x) (((x) & 0xF) << 24) + #define VM_CONTEXT1_CNTL 0x1414 + #define VM_CONTEXT0_CNTL2 0x1430 + #define VM_CONTEXT1_CNTL2 0x1434 +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 06b3375..c639a58 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -830,7 +830,7 @@ struct radeon_mec { + /* defines number of bits in page table versus page directory, + * a page is 4KB so we have 12 bits offset, 9 bits in the page + * table and the remaining 19 bits are in the page directory */ +-#define RADEON_VM_BLOCK_SIZE 9 ++#define RADEON_VM_BLOCK_SIZE 12 + + /* number of entries in page table */ + #define RADEON_VM_PTE_COUNT (1 << RADEON_VM_BLOCK_SIZE) +diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c +index f960ce6..34b09ac 100644 +--- a/drivers/gpu/drm/radeon/radeon_gart.c ++++ b/drivers/gpu/drm/radeon/radeon_gart.c +@@ -959,6 +959,7 @@ static int radeon_vm_update_pdes(struct radeon_device *rdev, + uint64_t start, uint64_t end) + { + static const uint32_t incr = RADEON_VM_PTE_COUNT * 8; ++ const unsigned align = min((uint32_t)RADEON_VM_PTB_ALIGN_SIZE, incr); + + uint64_t last_pde = ~0, last_pt = ~0; + unsigned count = 0; +@@ -979,7 +980,7 @@ retry: + r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, + &vm->page_tables[pt_idx], + RADEON_VM_PTE_COUNT * 8, +- RADEON_GPU_PAGE_SIZE, false); ++ align, false); + + if (r == -ENOMEM) { + r = radeon_vm_evict(rdev, vm); +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index d9173ef..a7c53b7 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -3979,6 +3979,7 @@ static int si_pcie_gart_enable(struct radeon_device *rdev) + (u32)(rdev->dummy_page.addr >> 12)); + WREG32(VM_CONTEXT1_CNTL2, 4); + WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) | ++ PAGE_TABLE_BLOCK_SIZE(RADEON_VM_BLOCK_SIZE - 9) | + RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT | + RANGE_PROTECTION_FAULT_ENABLE_DEFAULT | + DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT | +diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h +index 6e23019..db3dd87 100644 +--- a/drivers/gpu/drm/radeon/sid.h ++++ b/drivers/gpu/drm/radeon/sid.h +@@ -357,6 +357,7 @@ + #define READ_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 16) + #define WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 18) + #define WRITE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 19) ++#define PAGE_TABLE_BLOCK_SIZE(x) (((x) & 0xF) << 24) + #define VM_CONTEXT1_CNTL 0x1414 + #define VM_CONTEXT0_CNTL2 0x1430 + #define VM_CONTEXT1_CNTL2 0x1434 +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0020-yocto-amd-drm-radeon-WIP-add-copy-trace-point.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0020-yocto-amd-drm-radeon-WIP-add-copy-trace-point.patch new file mode 100644 index 00000000..95662197 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0020-yocto-amd-drm-radeon-WIP-add-copy-trace-point.patch @@ -0,0 +1,59 @@ +From fd743f086a3079b5fab5f05809a5998200f5201d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Tue, 17 Dec 2013 11:43:21 -0700 +Subject: [PATCH 20/44] drm/radeon: WIP add copy trace point +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/cik_sdma.c | 2 ++ + drivers/gpu/drm/radeon/radeon_trace.h | 18 ++++++++++++++++++ + 2 files changed, 20 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c +index 8517a62..a589d79 100644 +--- a/drivers/gpu/drm/radeon/cik_sdma.c ++++ b/drivers/gpu/drm/radeon/cik_sdma.c +@@ -433,6 +433,8 @@ int cik_copy_dma(struct radeon_device *rdev, + int i, num_loops; + int r = 0; + ++ trace_radeon_copy(src_offset, dst_offset, num_gpu_pages); ++ + r = radeon_semaphore_create(rdev, &sem); + if (r) { + DRM_ERROR("radeon: moving bo (%d).\n", r); +diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h +index 0473257..6e966bb 100644 +--- a/drivers/gpu/drm/radeon/radeon_trace.h ++++ b/drivers/gpu/drm/radeon/radeon_trace.h +@@ -27,6 +27,24 @@ TRACE_EVENT(radeon_bo_create, + TP_printk("bo=%p, pages=%u", __entry->bo, __entry->pages) + ); + ++TRACE_EVENT(radeon_copy, ++ TP_PROTO(u64 src, u64 dst, u32 pages), ++ TP_ARGS(src, dst, pages), ++ TP_STRUCT__entry( ++ __field(u64, src) ++ __field(u64, dst) ++ __field(u32, pages) ++ ), ++ ++ TP_fast_assign( ++ __entry->src = src; ++ __entry->dst = dst; ++ __entry->pages = pages; ++ ), ++ TP_printk("src=%010llx, dst=%010llx, pages=%u", ++ __entry->src, __entry->dst, __entry->pages) ++); ++ + TRACE_EVENT(radeon_cs, + TP_PROTO(struct radeon_cs_parser *p), + TP_ARGS(p), +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0021-yocto-amd-drm-radeon-cik-Return-backend-map-information-to-use.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0021-yocto-amd-drm-radeon-cik-Return-backend-map-information-to-use.patch new file mode 100644 index 00000000..d082f22c --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0021-yocto-amd-drm-radeon-cik-Return-backend-map-information-to-use.patch @@ -0,0 +1,34 @@ +From 72285aebc730c0b21532a0c5c83aa3f7d075e5ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com> +Date: Mon, 18 Nov 2013 18:25:59 +0900 +Subject: [PATCH 21/44] drm/radeon/cik: Return backend map information to + userspace +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is required to properly calculate the tiling parameters +in userspace. + +Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/radeon_kms.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +index 4a3b3c5..405b0d4 100644 +--- a/drivers/gpu/drm/radeon/radeon_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_kms.c +@@ -324,7 +324,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) + break; + case RADEON_INFO_BACKEND_MAP: + if (rdev->family >= CHIP_BONAIRE) +- return -EINVAL; ++ *value = rdev->config.cik.backend_map; + else if (rdev->family >= CHIP_TAHITI) + *value = rdev->config.si.backend_map; + else if (rdev->family >= CHIP_CAYMAN) +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0022-yocto-amd-drm-radeon-cik-Add-macrotile-mode-array-query.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0022-yocto-amd-drm-radeon-cik-Add-macrotile-mode-array-query.patch new file mode 100644 index 00000000..63d826e6 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0022-yocto-amd-drm-radeon-cik-Add-macrotile-mode-array-query.patch @@ -0,0 +1,113 @@ +From 93ebc5801cab1c47f426da110d19b77f71a51b4f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com> +Date: Mon, 18 Nov 2013 18:26:00 +0900 +Subject: [PATCH 22/44] drm/radeon/cik: Add macrotile mode array query +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is required to properly calculate the tiling parameters +in userspace. + +Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/cik.c | 3 +++ + drivers/gpu/drm/radeon/radeon.h | 1 + + drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- + drivers/gpu/drm/radeon/radeon_kms.c | 9 +++++++++ + include/uapi/drm/radeon_drm.h | 2 ++ + 5 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index cd5f85e..5419abe 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -1981,6 +1981,7 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev) + gb_tile_moden = 0; + break; + } ++ rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden; + WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden); + } + } else if (num_pipe_configs == 4) { +@@ -2327,6 +2328,7 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev) + gb_tile_moden = 0; + break; + } ++ rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden; + WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden); + } + } else if (num_pipe_configs == 2) { +@@ -2544,6 +2546,7 @@ static void cik_tiling_mode_table_init(struct radeon_device *rdev) + gb_tile_moden = 0; + break; + } ++ rdev->config.cik.macrotile_mode_array[reg_offset] = gb_tile_moden; + WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden); + } + } else +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index c639a58..5331fc2 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -1991,6 +1991,7 @@ struct cik_asic { + + unsigned tile_config; + uint32_t tile_mode_array[32]; ++ uint32_t macrotile_mode_array[16]; + }; + + union radeon_asic_config { +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index 9c14a1b..51b3214 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -75,9 +75,10 @@ + * 2.32.0 - new info request for rings working + * 2.33.0 - Add SI tiling mode array query + * 2.34.0 - Add CIK tiling mode array query ++ * 2.35.0 - Add CIK macrotile mode array query + */ + #define KMS_DRIVER_MAJOR 2 +-#define KMS_DRIVER_MINOR 34 ++#define KMS_DRIVER_MINOR 35 + #define KMS_DRIVER_PATCHLEVEL 0 + int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); + int radeon_driver_unload_kms(struct drm_device *dev); +diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +index 405b0d4..5d67422 100644 +--- a/drivers/gpu/drm/radeon/radeon_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_kms.c +@@ -433,6 +433,15 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) + return -EINVAL; + } + break; ++ case RADEON_INFO_CIK_MACROTILE_MODE_ARRAY: ++ if (rdev->family >= CHIP_BONAIRE) { ++ value = rdev->config.cik.macrotile_mode_array; ++ value_size = sizeof(uint32_t)*16; ++ } else { ++ DRM_DEBUG_KMS("macrotile mode array is cik+ only!\n"); ++ return -EINVAL; ++ } ++ break; + case RADEON_INFO_SI_CP_DMA_COMPUTE: + *value = 1; + break; +diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h +index a71442b..fe421e8 100644 +--- a/include/uapi/drm/radeon_drm.h ++++ b/include/uapi/drm/radeon_drm.h +@@ -981,6 +981,8 @@ struct drm_radeon_cs { + #define RADEON_INFO_SI_TILE_MODE_ARRAY 0x16 + /* query if CP DMA is supported on the compute ring */ + #define RADEON_INFO_SI_CP_DMA_COMPUTE 0x17 ++/* CIK macrotile mode array */ ++#define RADEON_INFO_CIK_MACROTILE_MODE_ARRAY 0x18 + /* query the number of render backends */ + #define RADEON_INFO_SI_BACKEND_ENABLED_MASK 0x19 + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0023-yocto-amd-drm-radeon-set-correct-number-of-banks-for-CIK-chips.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0023-yocto-amd-drm-radeon-set-correct-number-of-banks-for-CIK-chips.patch new file mode 100644 index 00000000..def7d8fc --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0023-yocto-amd-drm-radeon-set-correct-number-of-banks-for-CIK-chips.patch @@ -0,0 +1,102 @@ +From 037690c12dcf3c3c2843f8db082ad2f5d49b7757 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= <marek.olsak@amd.com> +Date: Mon, 23 Dec 2013 17:11:36 +0100 +Subject: [PATCH 23/44] drm/radeon: set correct number of banks for CIK chips + in DCE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We don't have the NUM_BANKS parameter, so we have to calculate it +from the other parameters. NUM_BANKS is not constant on CIK. + +This fixes 2D tiling for the display engine on CIK. + +Signed-off-by: Marek Olšák <marek.olsak@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/atombios_crtc.c | 64 +++++++++++++++++++++----------- + 1 file changed, 43 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c +index 368e1b8..09b35c3 100644 +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -1143,31 +1143,53 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, + } + + if (tiling_flags & RADEON_TILING_MACRO) { +- if (rdev->family >= CHIP_BONAIRE) +- tmp = rdev->config.cik.tile_config; +- else if (rdev->family >= CHIP_TAHITI) +- tmp = rdev->config.si.tile_config; +- else if (rdev->family >= CHIP_CAYMAN) +- tmp = rdev->config.cayman.tile_config; +- else +- tmp = rdev->config.evergreen.tile_config; ++ evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); + +- switch ((tmp & 0xf0) >> 4) { +- case 0: /* 4 banks */ +- fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK); +- break; +- case 1: /* 8 banks */ +- default: +- fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK); +- break; +- case 2: /* 16 banks */ +- fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK); +- break; ++ /* Set NUM_BANKS. */ ++ if (rdev->family >= CHIP_BONAIRE) { ++ unsigned tileb, index, num_banks, tile_split_bytes; ++ ++ /* Calculate the macrotile mode index. */ ++ tile_split_bytes = 64 << tile_split; ++ tileb = 8 * 8 * target_fb->bits_per_pixel / 8; ++ tileb = min(tile_split_bytes, tileb); ++ ++ for (index = 0; tileb > 64; index++) { ++ tileb >>= 1; ++ } ++ ++ if (index >= 16) { ++ DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n", ++ target_fb->bits_per_pixel, tile_split); ++ return -EINVAL; ++ } ++ ++ num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3; ++ fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks); ++ } else { ++ /* SI and older. */ ++ if (rdev->family >= CHIP_TAHITI) ++ tmp = rdev->config.si.tile_config; ++ else if (rdev->family >= CHIP_CAYMAN) ++ tmp = rdev->config.cayman.tile_config; ++ else ++ tmp = rdev->config.evergreen.tile_config; ++ ++ switch ((tmp & 0xf0) >> 4) { ++ case 0: /* 4 banks */ ++ fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK); ++ break; ++ case 1: /* 8 banks */ ++ default: ++ fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK); ++ break; ++ case 2: /* 16 banks */ ++ fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK); ++ break; ++ } + } + + fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); +- +- evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); + fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split); + fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw); + fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0024-yocto-amd-drm-radeon-don-t-power-gate-paused-UVD-streams.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0024-yocto-amd-drm-radeon-don-t-power-gate-paused-UVD-streams.patch new file mode 100644 index 00000000..8beb11e7 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0024-yocto-amd-drm-radeon-don-t-power-gate-paused-UVD-streams.patch @@ -0,0 +1,45 @@ +From e273f124b346f1fcbf3c363ae3224344988d07de Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Fri, 10 Jan 2014 06:59:40 -0700 +Subject: [PATCH 24/44] drm/radeon: don't power gate paused UVD streams +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon_pm.c | 4 ++++ + drivers/gpu/drm/radeon/radeon_uvd.c | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c +index 4f6b7fc..41ca652 100644 +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -938,6 +938,10 @@ void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable) + + if (rdev->asic->dpm.powergate_uvd) { + mutex_lock(&rdev->pm.mutex); ++ /* don't powergate anything if we ++ have active but pause streams */ ++ enable |= rdev->pm.dpm.sd > 0; ++ enable |= rdev->pm.dpm.hd > 0; + /* enable/disable UVD */ + radeon_dpm_powergate_uvd(rdev, !enable); + mutex_unlock(&rdev->pm.mutex); +diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c +index 2b502b4..1b5970a 100644 +--- a/drivers/gpu/drm/radeon/radeon_uvd.c ++++ b/drivers/gpu/drm/radeon/radeon_uvd.c +@@ -782,6 +782,8 @@ static void radeon_uvd_idle_work_handler(struct work_struct *work) + + if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0) { + if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { ++ radeon_uvd_count_handles(rdev, &rdev->pm.dpm.sd, ++ &rdev->pm.dpm.hd); + radeon_dpm_enable_uvd(rdev, false); + } else { + radeon_set_uvd_clocks(rdev, 0, 0); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0025-yocto-amd-drm-radeon-dpm-retain-user-selected-performance-leve.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0025-yocto-amd-drm-radeon-dpm-retain-user-selected-performance-leve.patch new file mode 100644 index 00000000..abec682c --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0025-yocto-amd-drm-radeon-dpm-retain-user-selected-performance-leve.patch @@ -0,0 +1,45 @@ +From b2773506c602407fc15219c75ec673d4bd0c2d82 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Wed, 23 Oct 2013 21:31:42 +0000 +Subject: [PATCH 25/44] drm/radeon/dpm: retain user selected performance level + across state changes + +If the user has forced the state high or low, retain that preference +even when we switch power states. + +Fixes: +https://bugs.freedesktop.org/show_bug.cgi?id=70654 + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/radeon_pm.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c +index 41ca652..5febb25 100644 +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -918,12 +918,16 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) + radeon_dpm_post_set_power_state(rdev); + + if (rdev->asic->dpm.force_performance_level) { +- if (rdev->pm.dpm.thermal_active) ++ if (rdev->pm.dpm.thermal_active) { ++ enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level; + /* force low perf level for thermal */ + radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_LOW); +- else +- /* otherwise, enable auto */ +- radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO); ++ /* save the user's level */ ++ rdev->pm.dpm.forced_level = level; ++ } else { ++ /* otherwise, user selected level */ ++ radeon_dpm_force_performance_level(rdev, rdev->pm.dpm.forced_level); ++ } + } + + done: +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0026-yocto-amd-drm-radeon-remove-generic-rptr-wptr-functions-v2.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0026-yocto-amd-drm-radeon-remove-generic-rptr-wptr-functions-v2.patch new file mode 100644 index 00000000..628a3230 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0026-yocto-amd-drm-radeon-remove-generic-rptr-wptr-functions-v2.patch @@ -0,0 +1,1049 @@ +From 3f033c032e0fd56dd58707405c037800f0f6fe90 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Tue, 10 Dec 2013 00:44:30 +0000 +Subject: [PATCH 26/44] drm/radeon: remove generic rptr/wptr functions (v2) + +Fill in asic family specific versions rather than +using the generic version. This lets us handle asic +specific differences more easily. In this case, we +disable sw swapping of the rtpr writeback value on +r6xx+ since the hw does it for us. Fixes bogus +rptr readback on BE systems. + +v2: remove missed cpu_to_le32(), add comments + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/cik.c | 58 +++++++++++++++++++--------- + drivers/gpu/drm/radeon/cik_sdma.c | 69 ++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/radeon/evergreen.c | 3 -- + drivers/gpu/drm/radeon/ni.c | 69 ++++++++++++++++++++++++++++++---- + drivers/gpu/drm/radeon/ni_dma.c | 69 ++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/radeon/r100.c | 31 ++++++++++++++- + drivers/gpu/drm/radeon/r600.c | 32 +++++++++++++++- + drivers/gpu/drm/radeon/r600_dma.c | 13 +++++-- + drivers/gpu/drm/radeon/radeon.h | 4 +- + drivers/gpu/drm/radeon/radeon_asic.c | 66 ++++++++++++++++---------------- + drivers/gpu/drm/radeon/radeon_asic.h | 57 +++++++++++++++++++++------- + drivers/gpu/drm/radeon/radeon_ring.c | 44 +++------------------- + drivers/gpu/drm/radeon/rv770.c | 3 -- + drivers/gpu/drm/radeon/si.c | 8 ---- + 14 files changed, 392 insertions(+), 134 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index 5419abe..4a89b5c 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -3461,15 +3461,43 @@ static int cik_cp_gfx_resume(struct radeon_device *rdev) + return 0; + } + +-u32 cik_compute_ring_get_rptr(struct radeon_device *rdev, +- struct radeon_ring *ring) ++u32 cik_gfx_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) + { + u32 rptr; + ++ if (rdev->wb.enabled) ++ rptr = rdev->wb.wb[ring->rptr_offs/4]; ++ else ++ rptr = RREG32(CP_RB0_RPTR); ++ ++ return rptr; ++} + ++u32 cik_gfx_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 wptr; ++ ++ wptr = RREG32(CP_RB0_WPTR); ++ ++ return wptr; ++} ++ ++void cik_gfx_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ WREG32(CP_RB0_WPTR, ring->wptr); ++ (void)RREG32(CP_RB0_WPTR); ++} ++ ++u32 cik_compute_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 rptr; + + if (rdev->wb.enabled) { +- rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); ++ rptr = rdev->wb.wb[ring->rptr_offs/4]; + } else { + mutex_lock(&rdev->srbm_mutex); + cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); +@@ -3481,13 +3509,14 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev, + return rptr; + } + +-u32 cik_compute_ring_get_wptr(struct radeon_device *rdev, +- struct radeon_ring *ring) ++u32 cik_compute_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) + { + u32 wptr; + + if (rdev->wb.enabled) { +- wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]); ++ /* XXX check if swapping is necessary on BE */ ++ wptr = rdev->wb.wb[ring->wptr_offs/4]; + } else { + mutex_lock(&rdev->srbm_mutex); + cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); +@@ -3499,10 +3528,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev, + return wptr; + } + +-void cik_compute_ring_set_wptr(struct radeon_device *rdev, +- struct radeon_ring *ring) ++void cik_compute_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) + { +- rdev->wb.wb[ring->wptr_offs/4] = cpu_to_le32(ring->wptr); ++ /* XXX check if swapping is necessary on BE */ ++ rdev->wb.wb[ring->wptr_offs/4] = ring->wptr; + WDOORBELL32(ring->doorbell_offset, ring->wptr); + } + +@@ -7058,8 +7088,7 @@ static int cik_startup(struct radeon_device *rdev) + + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, +- CP_RB0_RPTR, CP_RB0_WPTR, +- RADEON_CP_PACKET2); ++ PACKET3(PACKET3_NOP, 0x3FFF)); + if (r) + return r; + +@@ -7067,7 +7096,6 @@ static int cik_startup(struct radeon_device *rdev) + /* type-2 packets are deprecated on MEC, use type-3 instead */ + ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET, +- CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR, + PACKET3(PACKET3_NOP, 0x3FFF)); + if (r) + return r; +@@ -7079,7 +7107,6 @@ static int cik_startup(struct radeon_device *rdev) + /* type-2 packets are deprecated on MEC, use type-3 instead */ + ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET, +- CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR, + PACKET3(PACKET3_NOP, 0x3FFF)); + if (r) + return r; +@@ -7091,16 +7118,12 @@ static int cik_startup(struct radeon_device *rdev) + + ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, +- SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET, +- SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET, + SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0)); + if (r) + return r; + + ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, +- SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET, +- SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET, + SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0)); + if (r) + return r; +@@ -7116,7 +7139,6 @@ static int cik_startup(struct radeon_device *rdev) + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + if (ring->ring_size) { + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, +- UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, + RADEON_CP_PACKET2); + if (!r) + r = uvd_v1_0_init(rdev); +diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c +index a589d79..f7c0b47 100644 +--- a/drivers/gpu/drm/radeon/cik_sdma.c ++++ b/drivers/gpu/drm/radeon/cik_sdma.c +@@ -60,6 +60,75 @@ static void cik_sdma_hdp_flush(struct radeon_device *rdev, + } + + /** ++ * cik_sdma_get_rptr - get the current read pointer ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon ring pointer ++ * ++ * Get the current rptr from the hardware (CIK+). ++ */ ++uint32_t cik_sdma_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 rptr, reg; ++ ++ if (rdev->wb.enabled) { ++ rptr = rdev->wb.wb[ring->rptr_offs/4]; ++ } else { ++ if (ring->idx == R600_RING_TYPE_DMA_INDEX) ++ reg = SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET; ++ else ++ reg = SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET; ++ ++ rptr = RREG32(reg); ++ } ++ ++ return (rptr & 0x3fffc) >> 2; ++} ++ ++/** ++ * cik_sdma_get_wptr - get the current write pointer ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon ring pointer ++ * ++ * Get the current wptr from the hardware (CIK+). ++ */ ++uint32_t cik_sdma_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 reg; ++ ++ if (ring->idx == R600_RING_TYPE_DMA_INDEX) ++ reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET; ++ else ++ reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET; ++ ++ return (RREG32(reg) & 0x3fffc) >> 2; ++} ++ ++/** ++ * cik_sdma_set_wptr - commit the write pointer ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon ring pointer ++ * ++ * Write the wptr back to the hardware (CIK+). ++ */ ++void cik_sdma_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 reg; ++ ++ if (ring->idx == R600_RING_TYPE_DMA_INDEX) ++ reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET; ++ else ++ reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET; ++ ++ WREG32(reg, (ring->wptr << 2) & 0x3fffc); ++} ++ ++/** + * cik_sdma_ring_ib_execute - Schedule an IB on the DMA engine + * + * @rdev: radeon_device pointer +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index b5c67a9..491d048 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -5150,14 +5150,12 @@ static int evergreen_startup(struct radeon_device *rdev) + + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, +- R600_CP_RB_RPTR, R600_CP_RB_WPTR, + RADEON_CP_PACKET2); + if (r) + return r; + + ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, +- DMA_RB_RPTR, DMA_RB_WPTR, + DMA_PACKET(DMA_PACKET_NOP, 0, 0)); + if (r) + return r; +@@ -5175,7 +5173,6 @@ static int evergreen_startup(struct radeon_device *rdev) + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + if (ring->ring_size) { + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, +- UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, + RADEON_CP_PACKET2); + if (!r) + r = uvd_v1_0_init(rdev); +diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c +index ce87221..b684fd0 100644 +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -1401,6 +1401,55 @@ static void cayman_cp_enable(struct radeon_device *rdev, bool enable) + } + } + ++u32 cayman_gfx_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 rptr; ++ ++ if (rdev->wb.enabled) ++ rptr = rdev->wb.wb[ring->rptr_offs/4]; ++ else { ++ if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) ++ rptr = RREG32(CP_RB0_RPTR); ++ else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) ++ rptr = RREG32(CP_RB1_RPTR); ++ else ++ rptr = RREG32(CP_RB2_RPTR); ++ } ++ ++ return rptr; ++} ++ ++u32 cayman_gfx_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 wptr; ++ ++ if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) ++ wptr = RREG32(CP_RB0_WPTR); ++ else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) ++ wptr = RREG32(CP_RB1_WPTR); ++ else ++ wptr = RREG32(CP_RB2_WPTR); ++ ++ return wptr; ++} ++ ++void cayman_gfx_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) { ++ WREG32(CP_RB0_WPTR, ring->wptr); ++ (void)RREG32(CP_RB0_WPTR); ++ } else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) { ++ WREG32(CP_RB1_WPTR, ring->wptr); ++ (void)RREG32(CP_RB1_WPTR); ++ } else { ++ WREG32(CP_RB2_WPTR, ring->wptr); ++ (void)RREG32(CP_RB2_WPTR); ++ } ++} ++ + static int cayman_cp_load_microcode(struct radeon_device *rdev) + { + const __be32 *fw_data; +@@ -1529,6 +1578,16 @@ static int cayman_cp_resume(struct radeon_device *rdev) + CP_RB1_BASE, + CP_RB2_BASE + }; ++ static const unsigned cp_rb_rptr[] = { ++ CP_RB0_RPTR, ++ CP_RB1_RPTR, ++ CP_RB2_RPTR ++ }; ++ static const unsigned cp_rb_wptr[] = { ++ CP_RB0_WPTR, ++ CP_RB1_WPTR, ++ CP_RB2_WPTR ++ }; + struct radeon_ring *ring; + int i, r; + +@@ -1587,8 +1646,8 @@ static int cayman_cp_resume(struct radeon_device *rdev) + WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA); + + ring->rptr = ring->wptr = 0; +- WREG32(ring->rptr_reg, ring->rptr); +- WREG32(ring->wptr_reg, ring->wptr); ++ WREG32(cp_rb_rptr[i], ring->rptr); ++ WREG32(cp_rb_wptr[i], ring->wptr); + + mdelay(1); + WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA); +@@ -1984,23 +2043,18 @@ static int cayman_startup(struct radeon_device *rdev) + evergreen_irq_set(rdev); + + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, +- CP_RB0_RPTR, CP_RB0_WPTR, + RADEON_CP_PACKET2); + if (r) + return r; + + ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, +- DMA_RB_RPTR + DMA0_REGISTER_OFFSET, +- DMA_RB_WPTR + DMA0_REGISTER_OFFSET, + DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); + if (r) + return r; + + ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, +- DMA_RB_RPTR + DMA1_REGISTER_OFFSET, +- DMA_RB_WPTR + DMA1_REGISTER_OFFSET, + DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); + if (r) + return r; +@@ -2019,7 +2073,6 @@ static int cayman_startup(struct radeon_device *rdev) + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + if (ring->ring_size) { + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, +- UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, + RADEON_CP_PACKET2); + if (!r) + r = uvd_v1_0_init(rdev); +diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c +index bdeb65e..51424ab 100644 +--- a/drivers/gpu/drm/radeon/ni_dma.c ++++ b/drivers/gpu/drm/radeon/ni_dma.c +@@ -43,6 +43,75 @@ u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev); + */ + + /** ++ * cayman_dma_get_rptr - get the current read pointer ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon ring pointer ++ * ++ * Get the current rptr from the hardware (cayman+). ++ */ ++uint32_t cayman_dma_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 rptr, reg; ++ ++ if (rdev->wb.enabled) { ++ rptr = rdev->wb.wb[ring->rptr_offs/4]; ++ } else { ++ if (ring->idx == R600_RING_TYPE_DMA_INDEX) ++ reg = DMA_RB_RPTR + DMA0_REGISTER_OFFSET; ++ else ++ reg = DMA_RB_RPTR + DMA1_REGISTER_OFFSET; ++ ++ rptr = RREG32(reg); ++ } ++ ++ return (rptr & 0x3fffc) >> 2; ++} ++ ++/** ++ * cayman_dma_get_wptr - get the current write pointer ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon ring pointer ++ * ++ * Get the current wptr from the hardware (cayman+). ++ */ ++uint32_t cayman_dma_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 reg; ++ ++ if (ring->idx == R600_RING_TYPE_DMA_INDEX) ++ reg = DMA_RB_WPTR + DMA0_REGISTER_OFFSET; ++ else ++ reg = DMA_RB_WPTR + DMA1_REGISTER_OFFSET; ++ ++ return (RREG32(reg) & 0x3fffc) >> 2; ++} ++ ++/** ++ * cayman_dma_set_wptr - commit the write pointer ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon ring pointer ++ * ++ * Write the wptr back to the hardware (cayman+). ++ */ ++void cayman_dma_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 reg; ++ ++ if (ring->idx == R600_RING_TYPE_DMA_INDEX) ++ reg = DMA_RB_WPTR + DMA0_REGISTER_OFFSET; ++ else ++ reg = DMA_RB_WPTR + DMA1_REGISTER_OFFSET; ++ ++ WREG32(reg, (ring->wptr << 2) & 0x3fffc); ++} ++ ++/** + * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine + * + * @rdev: radeon_device pointer +diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c +index aa015a5..39f6984 100644 +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -1050,6 +1050,36 @@ static int r100_cp_init_microcode(struct radeon_device *rdev) + return err; + } + ++u32 r100_gfx_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 rptr; ++ ++ if (rdev->wb.enabled) ++ rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); ++ else ++ rptr = RREG32(RADEON_CP_RB_RPTR); ++ ++ return rptr; ++} ++ ++u32 r100_gfx_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 wptr; ++ ++ wptr = RREG32(RADEON_CP_RB_WPTR); ++ ++ return wptr; ++} ++ ++void r100_gfx_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ WREG32(RADEON_CP_RB_WPTR, ring->wptr); ++ (void)RREG32(RADEON_CP_RB_WPTR); ++} ++ + static void r100_cp_load_microcode(struct radeon_device *rdev) + { + const __be32 *fw_data; +@@ -1102,7 +1132,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) + ring_size = (1 << (rb_bufsz + 1)) * 4; + r100_cp_load_microcode(rdev); + r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET, +- RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR, + RADEON_CP_PACKET2); + if (r) { + return r; +diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c +index a5de2cf..5f52b50 100644 +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -2329,6 +2329,36 @@ out: + return err; + } + ++u32 r600_gfx_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 rptr; ++ ++ if (rdev->wb.enabled) ++ rptr = rdev->wb.wb[ring->rptr_offs/4]; ++ else ++ rptr = RREG32(R600_CP_RB_RPTR); ++ ++ return rptr; ++} ++ ++u32 r600_gfx_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ u32 wptr; ++ ++ wptr = RREG32(R600_CP_RB_WPTR); ++ ++ return wptr; ++} ++ ++void r600_gfx_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ WREG32(R600_CP_RB_WPTR, ring->wptr); ++ (void)RREG32(R600_CP_RB_WPTR); ++} ++ + static int r600_cp_load_microcode(struct radeon_device *rdev) + { + const __be32 *fw_data; +@@ -2773,14 +2803,12 @@ static int r600_startup(struct radeon_device *rdev) + + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, +- R600_CP_RB_RPTR, R600_CP_RB_WPTR, + RADEON_CP_PACKET2); + if (r) + return r; + + ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, +- DMA_RB_RPTR, DMA_RB_WPTR, + DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); + if (r) + return r; +diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c +index 7844d15..3452c84 100644 +--- a/drivers/gpu/drm/radeon/r600_dma.c ++++ b/drivers/gpu/drm/radeon/r600_dma.c +@@ -51,7 +51,14 @@ u32 r600_gpu_check_soft_reset(struct radeon_device *rdev); + uint32_t r600_dma_get_rptr(struct radeon_device *rdev, + struct radeon_ring *ring) + { +- return (radeon_ring_generic_get_rptr(rdev, ring) & 0x3fffc) >> 2; ++ u32 rptr; ++ ++ if (rdev->wb.enabled) ++ rptr = rdev->wb.wb[ring->rptr_offs/4]; ++ else ++ rptr = RREG32(DMA_RB_RPTR); ++ ++ return (rptr & 0x3fffc) >> 2; + } + + /** +@@ -65,7 +72,7 @@ uint32_t r600_dma_get_rptr(struct radeon_device *rdev, + uint32_t r600_dma_get_wptr(struct radeon_device *rdev, + struct radeon_ring *ring) + { +- return (RREG32(ring->wptr_reg) & 0x3fffc) >> 2; ++ return (RREG32(DMA_RB_WPTR) & 0x3fffc) >> 2; + } + + /** +@@ -79,7 +86,7 @@ uint32_t r600_dma_get_wptr(struct radeon_device *rdev, + void r600_dma_set_wptr(struct radeon_device *rdev, + struct radeon_ring *ring) + { +- WREG32(ring->wptr_reg, (ring->wptr << 2) & 0x3fffc); ++ WREG32(DMA_RB_WPTR, (ring->wptr << 2) & 0x3fffc); + } + + /** +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 5331fc2..fb7323d 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -782,13 +782,11 @@ struct radeon_ring { + volatile uint32_t *ring; + unsigned rptr; + unsigned rptr_offs; +- unsigned rptr_reg; + unsigned rptr_save_reg; + u64 next_rptr_gpu_addr; + volatile u32 *next_rptr_cpu_addr; + unsigned wptr; + unsigned wptr_old; +- unsigned wptr_reg; + unsigned ring_size; + unsigned ring_free_dw; + int count_dw; +@@ -960,7 +958,7 @@ unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring + int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned size, uint32_t *data); + int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, +- unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, u32 nop); ++ unsigned rptr_offs, u32 nop); + void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp); + + +diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c +index 123adfe..a539869 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.c ++++ b/drivers/gpu/drm/radeon/radeon_asic.c +@@ -182,9 +182,9 @@ static struct radeon_asic_ring r100_gfx_ring = { + .ring_test = &r100_ring_test, + .ib_test = &r100_ib_test, + .is_lockup = &r100_gpu_is_lockup, +- .get_rptr = &radeon_ring_generic_get_rptr, +- .get_wptr = &radeon_ring_generic_get_wptr, +- .set_wptr = &radeon_ring_generic_set_wptr, ++ .get_rptr = &r100_gfx_get_rptr, ++ .get_wptr = &r100_gfx_get_wptr, ++ .set_wptr = &r100_gfx_set_wptr, + }; + + static struct radeon_asic r100_asic = { +@@ -330,9 +330,9 @@ static struct radeon_asic_ring r300_gfx_ring = { + .ring_test = &r100_ring_test, + .ib_test = &r100_ib_test, + .is_lockup = &r100_gpu_is_lockup, +- .get_rptr = &radeon_ring_generic_get_rptr, +- .get_wptr = &radeon_ring_generic_get_wptr, +- .set_wptr = &radeon_ring_generic_set_wptr, ++ .get_rptr = &r100_gfx_get_rptr, ++ .get_wptr = &r100_gfx_get_wptr, ++ .set_wptr = &r100_gfx_set_wptr, + }; + + static struct radeon_asic r300_asic = { +@@ -883,9 +883,9 @@ static struct radeon_asic_ring r600_gfx_ring = { + .ring_test = &r600_ring_test, + .ib_test = &r600_ib_test, + .is_lockup = &r600_gfx_is_lockup, +- .get_rptr = &radeon_ring_generic_get_rptr, +- .get_wptr = &radeon_ring_generic_get_wptr, +- .set_wptr = &radeon_ring_generic_set_wptr, ++ .get_rptr = &r600_gfx_get_rptr, ++ .get_wptr = &r600_gfx_get_wptr, ++ .set_wptr = &r600_gfx_set_wptr, + }; + + static struct radeon_asic_ring r600_dma_ring = { +@@ -1267,9 +1267,9 @@ static struct radeon_asic_ring evergreen_gfx_ring = { + .ring_test = &r600_ring_test, + .ib_test = &r600_ib_test, + .is_lockup = &evergreen_gfx_is_lockup, +- .get_rptr = &radeon_ring_generic_get_rptr, +- .get_wptr = &radeon_ring_generic_get_wptr, +- .set_wptr = &radeon_ring_generic_set_wptr, ++ .get_rptr = &r600_gfx_get_rptr, ++ .get_wptr = &r600_gfx_get_wptr, ++ .set_wptr = &r600_gfx_set_wptr, + }; + + static struct radeon_asic_ring evergreen_dma_ring = { +@@ -1570,9 +1570,9 @@ static struct radeon_asic_ring cayman_gfx_ring = { + .ib_test = &r600_ib_test, + .is_lockup = &cayman_gfx_is_lockup, + .vm_flush = &cayman_vm_flush, +- .get_rptr = &radeon_ring_generic_get_rptr, +- .get_wptr = &radeon_ring_generic_get_wptr, +- .set_wptr = &radeon_ring_generic_set_wptr, ++ .get_rptr = &cayman_gfx_get_rptr, ++ .get_wptr = &cayman_gfx_get_wptr, ++ .set_wptr = &cayman_gfx_set_wptr, + }; + + static struct radeon_asic_ring cayman_dma_ring = { +@@ -1585,9 +1585,9 @@ static struct radeon_asic_ring cayman_dma_ring = { + .ib_test = &r600_dma_ib_test, + .is_lockup = &cayman_dma_is_lockup, + .vm_flush = &cayman_dma_vm_flush, +- .get_rptr = &r600_dma_get_rptr, +- .get_wptr = &r600_dma_get_wptr, +- .set_wptr = &r600_dma_set_wptr ++ .get_rptr = &cayman_dma_get_rptr, ++ .get_wptr = &cayman_dma_get_wptr, ++ .set_wptr = &cayman_dma_set_wptr + }; + + static struct radeon_asic_ring cayman_uvd_ring = { +@@ -1813,9 +1813,9 @@ static struct radeon_asic_ring si_gfx_ring = { + .ib_test = &r600_ib_test, + .is_lockup = &si_gfx_is_lockup, + .vm_flush = &si_vm_flush, +- .get_rptr = &radeon_ring_generic_get_rptr, +- .get_wptr = &radeon_ring_generic_get_wptr, +- .set_wptr = &radeon_ring_generic_set_wptr, ++ .get_rptr = &cayman_gfx_get_rptr, ++ .get_wptr = &cayman_gfx_get_wptr, ++ .set_wptr = &cayman_gfx_set_wptr, + }; + + static struct radeon_asic_ring si_dma_ring = { +@@ -1828,9 +1828,9 @@ static struct radeon_asic_ring si_dma_ring = { + .ib_test = &r600_dma_ib_test, + .is_lockup = &si_dma_is_lockup, + .vm_flush = &si_dma_vm_flush, +- .get_rptr = &r600_dma_get_rptr, +- .get_wptr = &r600_dma_get_wptr, +- .set_wptr = &r600_dma_set_wptr, ++ .get_rptr = &cayman_dma_get_rptr, ++ .get_wptr = &cayman_dma_get_wptr, ++ .set_wptr = &cayman_dma_set_wptr, + }; + + static struct radeon_asic si_asic = { +@@ -1943,9 +1943,9 @@ static struct radeon_asic_ring ci_gfx_ring = { + .ib_test = &cik_ib_test, + .is_lockup = &cik_gfx_is_lockup, + .vm_flush = &cik_vm_flush, +- .get_rptr = &radeon_ring_generic_get_rptr, +- .get_wptr = &radeon_ring_generic_get_wptr, +- .set_wptr = &radeon_ring_generic_set_wptr, ++ .get_rptr = &cik_gfx_get_rptr, ++ .get_wptr = &cik_gfx_get_wptr, ++ .set_wptr = &cik_gfx_set_wptr, + }; + + static struct radeon_asic_ring ci_cp_ring = { +@@ -1958,9 +1958,9 @@ static struct radeon_asic_ring ci_cp_ring = { + .ib_test = &cik_ib_test, + .is_lockup = &cik_gfx_is_lockup, + .vm_flush = &cik_vm_flush, +- .get_rptr = &cik_compute_ring_get_rptr, +- .get_wptr = &cik_compute_ring_get_wptr, +- .set_wptr = &cik_compute_ring_set_wptr, ++ .get_rptr = &cik_compute_get_rptr, ++ .get_wptr = &cik_compute_get_wptr, ++ .set_wptr = &cik_compute_set_wptr, + }; + + static struct radeon_asic_ring ci_dma_ring = { +@@ -1973,9 +1973,9 @@ static struct radeon_asic_ring ci_dma_ring = { + .ib_test = &cik_sdma_ib_test, + .is_lockup = &cik_sdma_is_lockup, + .vm_flush = &cik_dma_vm_flush, +- .get_rptr = &r600_dma_get_rptr, +- .get_wptr = &r600_dma_get_wptr, +- .set_wptr = &r600_dma_set_wptr, ++ .get_rptr = &cik_sdma_get_rptr, ++ .get_wptr = &cik_sdma_get_wptr, ++ .set_wptr = &cik_sdma_set_wptr, + }; + + static struct radeon_asic ci_asic = { +diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h +index 8939cb3..998042e 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.h ++++ b/drivers/gpu/drm/radeon/radeon_asic.h +@@ -47,13 +47,6 @@ u8 atombios_get_backlight_level(struct radeon_encoder *radeon_encoder); + void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level); + u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder); + +-u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev, +- struct radeon_ring *ring); +-u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev, +- struct radeon_ring *ring); +-void radeon_ring_generic_set_wptr(struct radeon_device *rdev, +- struct radeon_ring *ring); +- + /* + * r100,rv100,rs100,rv200,rs200 + */ +@@ -148,6 +141,13 @@ extern void r100_post_page_flip(struct radeon_device *rdev, int crtc); + extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc); + extern int r100_mc_wait_for_idle(struct radeon_device *rdev); + ++u32 r100_gfx_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++u32 r100_gfx_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++void r100_gfx_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++ + /* + * r200,rv250,rs300,rv280 + */ +@@ -368,6 +368,12 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev); + int r600_pcie_gart_init(struct radeon_device *rdev); + void r600_scratch_init(struct radeon_device *rdev); + int r600_init_microcode(struct radeon_device *rdev); ++u32 r600_gfx_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++u32 r600_gfx_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++void r600_gfx_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); + /* r600 irq */ + int r600_irq_process(struct radeon_device *rdev); + int r600_irq_init(struct radeon_device *rdev); +@@ -591,6 +597,19 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev, + + void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); + ++u32 cayman_gfx_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++u32 cayman_gfx_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++void cayman_gfx_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++uint32_t cayman_dma_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++uint32_t cayman_dma_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++void cayman_dma_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++ + int ni_dpm_init(struct radeon_device *rdev); + void ni_dpm_setup_asic(struct radeon_device *rdev); + int ni_dpm_enable(struct radeon_device *rdev); +@@ -735,12 +754,24 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev, + uint32_t incr, uint32_t flags); + void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); + int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); +-u32 cik_compute_ring_get_rptr(struct radeon_device *rdev, +- struct radeon_ring *ring); +-u32 cik_compute_ring_get_wptr(struct radeon_device *rdev, +- struct radeon_ring *ring); +-void cik_compute_ring_set_wptr(struct radeon_device *rdev, +- struct radeon_ring *ring); ++u32 cik_gfx_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++u32 cik_gfx_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++void cik_gfx_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++u32 cik_compute_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++u32 cik_compute_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++void cik_compute_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++u32 cik_sdma_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++u32 cik_sdma_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++void cik_sdma_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); + int ci_get_temp(struct radeon_device *rdev); + int kv_get_temp(struct radeon_device *rdev); + +diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c +index f1cec22..65f1cea 100644 +--- a/drivers/gpu/drm/radeon/radeon_ring.c ++++ b/drivers/gpu/drm/radeon/radeon_ring.c +@@ -332,36 +332,6 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev, + } + } + +-u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev, +- struct radeon_ring *ring) +-{ +- u32 rptr; +- +- if (rdev->wb.enabled) +- rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); +- else +- rptr = RREG32(ring->rptr_reg); +- +- return rptr; +-} +- +-u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev, +- struct radeon_ring *ring) +-{ +- u32 wptr; +- +- wptr = RREG32(ring->wptr_reg); +- +- return wptr; +-} +- +-void radeon_ring_generic_set_wptr(struct radeon_device *rdev, +- struct radeon_ring *ring) +-{ +- WREG32(ring->wptr_reg, ring->wptr); +- (void)RREG32(ring->wptr_reg); +-} +- + /** + * radeon_ring_free_size - update the free size + * +@@ -689,22 +659,18 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, + * @ring: radeon_ring structure holding ring information + * @ring_size: size of the ring + * @rptr_offs: offset of the rptr writeback location in the WB buffer +- * @rptr_reg: MMIO offset of the rptr register +- * @wptr_reg: MMIO offset of the wptr register + * @nop: nop packet for this ring + * + * Initialize the driver information for the selected ring (all asics). + * Returns 0 on success, error on failure. + */ + int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, +- unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, u32 nop) ++ unsigned rptr_offs, u32 nop) + { + int r; + + ring->ring_size = ring_size; + ring->rptr_offs = rptr_offs; +- ring->rptr_reg = rptr_reg; +- ring->wptr_reg = wptr_reg; + ring->nop = nop; + /* Allocate ring buffer */ + if (ring->ring_obj == NULL) { +@@ -798,12 +764,12 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) + count = (ring->ring_size / 4) - ring->ring_free_dw; + + wptr = radeon_ring_get_wptr(rdev, ring); +- seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", +- ring->wptr_reg, wptr, wptr); ++ seq_printf(m, "wptr: 0x%08x [%5d]\n", ++ wptr, wptr); + + rptr = radeon_ring_get_rptr(rdev, ring); +- seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", +- ring->rptr_reg, rptr, rptr); ++ seq_printf(m, "rptr: 0x%08x [%5d]\n", ++ rptr, rptr); + + if (ring->rptr_save_reg) { + rptr_next = RREG32(ring->rptr_save_reg); +diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c +index 9f58467..6cce0de 100644 +--- a/drivers/gpu/drm/radeon/rv770.c ++++ b/drivers/gpu/drm/radeon/rv770.c +@@ -1728,14 +1728,12 @@ static int rv770_startup(struct radeon_device *rdev) + + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, +- R600_CP_RB_RPTR, R600_CP_RB_WPTR, + RADEON_CP_PACKET2); + if (r) + return r; + + ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, +- DMA_RB_RPTR, DMA_RB_WPTR, + DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); + if (r) + return r; +@@ -1754,7 +1752,6 @@ static int rv770_startup(struct radeon_device *rdev) + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + if (ring->ring_size) { + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, +- UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, + RADEON_CP_PACKET2); + if (!r) + r = uvd_v1_0_init(rdev); +diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c +index a7c53b7..8576a6f 100644 +--- a/drivers/gpu/drm/radeon/si.c ++++ b/drivers/gpu/drm/radeon/si.c +@@ -6424,37 +6424,30 @@ static int si_startup(struct radeon_device *rdev) + + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, +- CP_RB0_RPTR, CP_RB0_WPTR, + RADEON_CP_PACKET2); + if (r) + return r; + + ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET, +- CP_RB1_RPTR, CP_RB1_WPTR, + RADEON_CP_PACKET2); + if (r) + return r; + + ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET, +- CP_RB2_RPTR, CP_RB2_WPTR, + RADEON_CP_PACKET2); + if (r) + return r; + + ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, +- DMA_RB_RPTR + DMA0_REGISTER_OFFSET, +- DMA_RB_WPTR + DMA0_REGISTER_OFFSET, + DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0)); + if (r) + return r; + + ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; + r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, +- DMA_RB_RPTR + DMA1_REGISTER_OFFSET, +- DMA_RB_WPTR + DMA1_REGISTER_OFFSET, + DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0)); + if (r) + return r; +@@ -6474,7 +6467,6 @@ static int si_startup(struct radeon_device *rdev) + ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; + if (ring->ring_size) { + r = radeon_ring_init(rdev, ring, ring->ring_size, 0, +- UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, + RADEON_CP_PACKET2); + if (!r) + r = uvd_v1_0_init(rdev); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch new file mode 100644 index 00000000..e64abef2 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch @@ -0,0 +1,1434 @@ +From 5890ab59e66a268c7910a7a5ad939107fa1b8a1d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 23 May 2013 12:10:04 +0200 +Subject: [PATCH 27/44] drm/radeon: initial VCE support v4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Only VCE 2.0 support so far. + +v2: squashing multiple patches into this one +v3: add IRQ support for CIK, major cleanups, + basic code documentation +v4: remove HAINAN from chipset list + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/Makefile | 6 + + drivers/gpu/drm/radeon/cik.c | 60 ++++ + drivers/gpu/drm/radeon/cikd.h | 33 ++ + drivers/gpu/drm/radeon/radeon.h | 56 +++- + drivers/gpu/drm/radeon/radeon_asic.c | 17 + + drivers/gpu/drm/radeon/radeon_asic.h | 13 + + drivers/gpu/drm/radeon/radeon_cs.c | 4 + + drivers/gpu/drm/radeon/radeon_kms.c | 1 + + drivers/gpu/drm/radeon/radeon_ring.c | 4 + + drivers/gpu/drm/radeon/radeon_test.c | 39 ++- + drivers/gpu/drm/radeon/radeon_vce.c | 588 ++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/radeon/sid.h | 47 +++ + drivers/gpu/drm/radeon/vce_v1_0.c | 187 +++++++++++ + drivers/gpu/drm/radeon/vce_v2_0.c | 70 ++++ + include/uapi/drm/radeon_drm.h | 1 + + 15 files changed, 1117 insertions(+), 9 deletions(-) + create mode 100644 drivers/gpu/drm/radeon/radeon_vce.c + create mode 100644 drivers/gpu/drm/radeon/vce_v1_0.c + create mode 100644 drivers/gpu/drm/radeon/vce_v2_0.c + +diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile +index 306364a..ed60caa 100644 +--- a/drivers/gpu/drm/radeon/Makefile ++++ b/drivers/gpu/drm/radeon/Makefile +@@ -99,6 +99,12 @@ radeon-y += \ + uvd_v3_1.o \ + uvd_v4_2.o + ++# add VCE block ++radeon-y += \ ++ radeon_vce.o \ ++ vce_v1_0.o \ ++ vce_v2_0.o \ ++ + radeon-$(CONFIG_COMPAT) += radeon_ioc32.o + radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o + radeon-$(CONFIG_ACPI) += radeon_acpi.o +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index 4a89b5c..872b146 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -6753,6 +6753,20 @@ restart_ih: + /* reset addr and status */ + WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); + break; ++ case 167: /* VCE */ ++ DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data); ++ switch (src_data) { ++ case 0: ++ radeon_fence_process(rdev, TN_RING_TYPE_VCE1_INDEX); ++ break; ++ case 1: ++ radeon_fence_process(rdev, TN_RING_TYPE_VCE2_INDEX); ++ break; ++ default: ++ DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); ++ break; ++ } ++ break; + case 176: /* GFX RB CP_INT */ + case 177: /* GFX IB CP_INT */ + radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); +@@ -7071,6 +7085,22 @@ static int cik_startup(struct radeon_device *rdev) + if (r) + rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; + ++ r = radeon_vce_resume(rdev); ++ if (!r) { ++ r = vce_v2_0_resume(rdev); ++ if (!r) ++ r = radeon_fence_driver_start_ring(rdev, ++ TN_RING_TYPE_VCE1_INDEX); ++ if (!r) ++ r = radeon_fence_driver_start_ring(rdev, ++ TN_RING_TYPE_VCE2_INDEX); ++ } ++ if (r) { ++ dev_err(rdev->dev, "VCE init error (%d).\n", r); ++ rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; ++ rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; ++ } ++ + /* Enable IRQ */ + if (!rdev->irq.installed) { + r = radeon_irq_kms_init(rdev); +@@ -7146,6 +7176,23 @@ static int cik_startup(struct radeon_device *rdev) + DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); + } + ++ r = -ENOENT; ++ ++ ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; ++ if (ring->ring_size) ++ r = radeon_ring_init(rdev, ring, ring->ring_size, 0, ++ VCE_CMD_NO_OP); ++ ++ ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; ++ if (ring->ring_size) ++ r = radeon_ring_init(rdev, ring, ring->ring_size, 0, ++ VCE_CMD_NO_OP); ++ ++ if (!r) ++ r = vce_v1_0_init(rdev); ++ else if (r != -ENOENT) ++ DRM_ERROR("radeon: failed initializing VCE (%d).\n", r); ++ + r = radeon_ib_pool_init(rdev); + if (r) { + dev_err(rdev->dev, "IB initialization failed (%d).\n", r); +@@ -7213,6 +7260,7 @@ int cik_suspend(struct radeon_device *rdev) + cik_sdma_enable(rdev, false); + uvd_v1_0_fini(rdev); + radeon_uvd_suspend(rdev); ++ radeon_vce_suspend(rdev); + cik_fini_pg(rdev); + cik_fini_cg(rdev); + cik_irq_suspend(rdev); +@@ -7321,6 +7369,17 @@ int cik_init(struct radeon_device *rdev) + r600_ring_init(rdev, ring, 4096); + } + ++ r = radeon_vce_init(rdev); ++ if (!r) { ++ ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; ++ ring->ring_obj = NULL; ++ r600_ring_init(rdev, ring, 4096); ++ ++ ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; ++ ring->ring_obj = NULL; ++ r600_ring_init(rdev, ring, 4096); ++ } ++ + rdev->ih.ring_obj = NULL; + r600_ih_ring_init(rdev, 64 * 1024); + +@@ -7381,6 +7440,7 @@ void cik_fini(struct radeon_device *rdev) + radeon_irq_kms_fini(rdev); + uvd_v1_0_fini(rdev); + radeon_uvd_fini(rdev); ++ radeon_vce_fini(rdev); + cik_pcie_gart_fini(rdev); + r600_vram_scratch_fini(rdev); + radeon_gem_fini(rdev); +diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h +index 7a0a0d2..b296d50 100644 +--- a/drivers/gpu/drm/radeon/cikd.h ++++ b/drivers/gpu/drm/radeon/cikd.h +@@ -1899,4 +1899,37 @@ + /* UVD CTX indirect */ + #define UVD_CGC_MEM_CTRL 0xC0 + ++/* VCE */ ++ ++#define VCE_VCPU_CACHE_OFFSET0 0x20024 ++#define VCE_VCPU_CACHE_SIZE0 0x20028 ++#define VCE_VCPU_CACHE_OFFSET1 0x2002c ++#define VCE_VCPU_CACHE_SIZE1 0x20030 ++#define VCE_VCPU_CACHE_OFFSET2 0x20034 ++#define VCE_VCPU_CACHE_SIZE2 0x20038 ++#define VCE_RB_RPTR2 0x20178 ++#define VCE_RB_WPTR2 0x2017c ++#define VCE_RB_RPTR 0x2018c ++#define VCE_RB_WPTR 0x20190 ++#define VCE_CLOCK_GATING_A 0x202f8 ++#define VCE_CLOCK_GATING_B 0x202fc ++#define VCE_UENC_CLOCK_GATING 0x207bc ++#define VCE_UENC_REG_CLOCK_GATING 0x207c0 ++#define VCE_SYS_INT_EN 0x21300 ++# define VCE_SYS_INT_TRAP_INTERRUPT_EN (1 << 3) ++#define VCE_LMI_CTRL2 0x21474 ++#define VCE_LMI_CTRL 0x21498 ++#define VCE_LMI_VM_CTRL 0x214a0 ++#define VCE_LMI_SWAP_CNTL 0x214b4 ++#define VCE_LMI_SWAP_CNTL1 0x214b8 ++#define VCE_LMI_CACHE_CTRL 0x214f4 ++ ++#define VCE_CMD_NO_OP 0x00000000 ++#define VCE_CMD_END 0x00000001 ++#define VCE_CMD_IB 0x00000002 ++#define VCE_CMD_FENCE 0x00000003 ++#define VCE_CMD_TRAP 0x00000004 ++#define VCE_CMD_IB_AUTO 0x00000005 ++#define VCE_CMD_SEMAPHORE 0x00000006 ++ + #endif +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index fb7323d..094e5f5 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -111,19 +111,16 @@ extern int radeon_aspm; + #define RADEONFB_CONN_LIMIT 4 + #define RADEON_BIOS_NUM_SCRATCH 8 + +-/* max number of rings */ +-#define RADEON_NUM_RINGS 6 +- + /* fence seq are set to this number when signaled */ + #define RADEON_FENCE_SIGNALED_SEQ 0LL + + /* internal ring indices */ + /* r1xx+ has gfx CP ring */ +-#define RADEON_RING_TYPE_GFX_INDEX 0 ++#define RADEON_RING_TYPE_GFX_INDEX 0 + + /* cayman has 2 compute CP rings */ +-#define CAYMAN_RING_TYPE_CP1_INDEX 1 +-#define CAYMAN_RING_TYPE_CP2_INDEX 2 ++#define CAYMAN_RING_TYPE_CP1_INDEX 1 ++#define CAYMAN_RING_TYPE_CP2_INDEX 2 + + /* R600+ has an async dma ring */ + #define R600_RING_TYPE_DMA_INDEX 3 +@@ -131,7 +128,14 @@ extern int radeon_aspm; + #define CAYMAN_RING_TYPE_DMA1_INDEX 4 + + /* R600+ */ +-#define R600_RING_TYPE_UVD_INDEX 5 ++#define R600_RING_TYPE_UVD_INDEX 5 ++ ++/* TN+ */ ++#define TN_RING_TYPE_VCE1_INDEX 6 ++#define TN_RING_TYPE_VCE2_INDEX 7 ++ ++/* max number of rings */ ++#define RADEON_NUM_RINGS 8 + + /* hardcode those limit for now */ + #define RADEON_VA_IB_OFFSET (1 << 20) +@@ -1586,6 +1590,42 @@ int radeon_uvd_calc_upll_dividers(struct radeon_device *rdev, + int radeon_uvd_send_upll_ctlreq(struct radeon_device *rdev, + unsigned cg_upll_func_cntl); + ++/* ++ * VCE ++ */ ++#define RADEON_MAX_VCE_HANDLES 16 ++#define RADEON_VCE_STACK_SIZE (1024*1024) ++#define RADEON_VCE_HEAP_SIZE (4*1024*1024) ++ ++struct radeon_vce { ++ struct radeon_bo *vcpu_bo; ++ void *cpu_addr; ++ uint64_t gpu_addr; ++ atomic_t handles[RADEON_MAX_VCE_HANDLES]; ++ struct drm_file *filp[RADEON_MAX_VCE_HANDLES]; ++}; ++ ++int radeon_vce_init(struct radeon_device *rdev); ++void radeon_vce_fini(struct radeon_device *rdev); ++int radeon_vce_suspend(struct radeon_device *rdev); ++int radeon_vce_resume(struct radeon_device *rdev); ++int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring, ++ uint32_t handle, struct radeon_fence **fence); ++int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring, ++ uint32_t handle, struct radeon_fence **fence); ++void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp); ++int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi); ++int radeon_vce_cs_parse(struct radeon_cs_parser *p); ++bool radeon_vce_semaphore_emit(struct radeon_device *rdev, ++ struct radeon_ring *ring, ++ struct radeon_semaphore *semaphore, ++ bool emit_wait); ++void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); ++void radeon_vce_fence_emit(struct radeon_device *rdev, ++ struct radeon_fence *fence); ++int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring); ++int radeon_vce_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); ++ + struct r600_audio_pin { + int channels; + int rate; +@@ -2180,6 +2220,7 @@ struct radeon_device { + struct radeon_gem gem; + struct radeon_pm pm; + struct radeon_uvd uvd; ++ struct radeon_vce vce; + uint32_t bios_scratch[RADEON_BIOS_NUM_SCRATCH]; + struct radeon_wb wb; + struct radeon_dummy_page dummy_page; +@@ -2198,6 +2239,7 @@ struct radeon_device { + const struct firmware *sdma_fw; /* CIK SDMA firmware */ + const struct firmware *smc_fw; /* SMC firmware */ + const struct firmware *uvd_fw; /* UVD firmware */ ++ const struct firmware *vce_fw; /* VCE firmware */ + struct r600_vram_scratch vram_scratch; + int msi_enabled; /* msi enabled */ + struct r600_ih ih; /* r6/700 interrupt ring */ +diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c +index a539869..763280b 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.c ++++ b/drivers/gpu/drm/radeon/radeon_asic.c +@@ -1978,6 +1978,19 @@ static struct radeon_asic_ring ci_dma_ring = { + .set_wptr = &cik_sdma_set_wptr, + }; + ++static struct radeon_asic_ring ci_vce_ring = { ++ .ib_execute = &radeon_vce_ib_execute, ++ .emit_fence = &radeon_vce_fence_emit, ++ .emit_semaphore = &radeon_vce_semaphore_emit, ++ .cs_parse = &radeon_vce_cs_parse, ++ .ring_test = &radeon_vce_ring_test, ++ .ib_test = &radeon_vce_ib_test, ++ .is_lockup = &radeon_ring_test_lockup, ++ .get_rptr = &vce_v1_0_get_rptr, ++ .get_wptr = &vce_v1_0_get_wptr, ++ .set_wptr = &vce_v1_0_set_wptr, ++}; ++ + static struct radeon_asic ci_asic = { + .init = &cik_init, + .fini = &cik_fini, +@@ -2006,6 +2019,8 @@ static struct radeon_asic ci_asic = { + [R600_RING_TYPE_DMA_INDEX] = &ci_dma_ring, + [CAYMAN_RING_TYPE_DMA1_INDEX] = &ci_dma_ring, + [R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring, ++ [TN_RING_TYPE_VCE1_INDEX] = &ci_vce_ring, ++ [TN_RING_TYPE_VCE2_INDEX] = &ci_vce_ring, + }, + .irq = { + .set = &cik_irq_set, +@@ -2107,6 +2122,8 @@ static struct radeon_asic kv_asic = { + [R600_RING_TYPE_DMA_INDEX] = &ci_dma_ring, + [CAYMAN_RING_TYPE_DMA1_INDEX] = &ci_dma_ring, + [R600_RING_TYPE_UVD_INDEX] = &cayman_uvd_ring, ++ [TN_RING_TYPE_VCE1_INDEX] = &ci_vce_ring, ++ [TN_RING_TYPE_VCE2_INDEX] = &ci_vce_ring, + }, + .irq = { + .set = &cik_irq_set, +diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h +index 998042e..a6c3eeb 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.h ++++ b/drivers/gpu/drm/radeon/radeon_asic.h +@@ -850,4 +850,17 @@ bool uvd_v3_1_semaphore_emit(struct radeon_device *rdev, + /* uvd v4.2 */ + int uvd_v4_2_resume(struct radeon_device *rdev); + ++/* vce v1.0 */ ++uint32_t vce_v1_0_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++void vce_v1_0_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring); ++int vce_v1_0_init(struct radeon_device *rdev); ++int vce_v1_0_start(struct radeon_device *rdev); ++ ++/* vce v2.0 */ ++int vce_v2_0_resume(struct radeon_device *rdev); ++ + #endif +diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c +index 83731ff..2f8e92b 100644 +--- a/drivers/gpu/drm/radeon/radeon_cs.c ++++ b/drivers/gpu/drm/radeon/radeon_cs.c +@@ -147,6 +147,10 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority + case RADEON_CS_RING_UVD: + p->ring = R600_RING_TYPE_UVD_INDEX; + break; ++ case RADEON_CS_RING_VCE: ++ /* TODO: only use the low priority ring for now */ ++ p->ring = TN_RING_TYPE_VCE1_INDEX; ++ break; + } + return 0; + } +diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +index 5d67422..07da88f 100644 +--- a/drivers/gpu/drm/radeon/radeon_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_kms.c +@@ -579,6 +579,7 @@ void radeon_driver_preclose_kms(struct drm_device *dev, + if (rdev->cmask_filp == file_priv) + rdev->cmask_filp = NULL; + radeon_uvd_free_handles(rdev, file_priv); ++ radeon_vce_free_handles(rdev, file_priv); + } + + /* +diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c +index 65f1cea..91457f8 100644 +--- a/drivers/gpu/drm/radeon/radeon_ring.c ++++ b/drivers/gpu/drm/radeon/radeon_ring.c +@@ -814,6 +814,8 @@ static int cayman_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX; + static int radeon_dma1_index = R600_RING_TYPE_DMA_INDEX; + static int radeon_dma2_index = CAYMAN_RING_TYPE_DMA1_INDEX; + static int r600_uvd_index = R600_RING_TYPE_UVD_INDEX; ++static int si_vce1_index = TN_RING_TYPE_VCE1_INDEX; ++static int si_vce2_index = TN_RING_TYPE_VCE2_INDEX; + + static struct drm_info_list radeon_debugfs_ring_info_list[] = { + {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_gfx_index}, +@@ -822,6 +824,8 @@ static struct drm_info_list radeon_debugfs_ring_info_list[] = { + {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_dma1_index}, + {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_dma2_index}, + {"radeon_ring_uvd", radeon_debugfs_ring_info, 0, &r600_uvd_index}, ++ {"radeon_ring_vce1", radeon_debugfs_ring_info, 0, &si_vce1_index}, ++ {"radeon_ring_vce2", radeon_debugfs_ring_info, 0, &si_vce2_index}, + }; + + static int radeon_debugfs_sa_info(struct seq_file *m, void *data) +diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c +index 12e8099..3a13e0d 100644 +--- a/drivers/gpu/drm/radeon/radeon_test.c ++++ b/drivers/gpu/drm/radeon/radeon_test.c +@@ -257,20 +257,36 @@ static int radeon_test_create_and_emit_fence(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_fence **fence) + { ++ uint32_t handle = ring->idx ^ 0xdeafbeef; + int r; + + if (ring->idx == R600_RING_TYPE_UVD_INDEX) { +- r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL); ++ r = radeon_uvd_get_create_msg(rdev, ring->idx, handle, NULL); + if (r) { + DRM_ERROR("Failed to get dummy create msg\n"); + return r; + } + +- r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, fence); ++ r = radeon_uvd_get_destroy_msg(rdev, ring->idx, handle, fence); + if (r) { + DRM_ERROR("Failed to get dummy destroy msg\n"); + return r; + } ++ ++ } else if (ring->idx == TN_RING_TYPE_VCE1_INDEX || ++ ring->idx == TN_RING_TYPE_VCE2_INDEX) { ++ r = radeon_vce_get_create_msg(rdev, ring->idx, handle, NULL); ++ if (r) { ++ DRM_ERROR("Failed to get dummy create msg\n"); ++ return r; ++ } ++ ++ r = radeon_vce_get_destroy_msg(rdev, ring->idx, handle, fence); ++ if (r) { ++ DRM_ERROR("Failed to get dummy destroy msg\n"); ++ return r; ++ } ++ + } else { + r = radeon_ring_lock(rdev, ring, 64); + if (r) { +@@ -486,6 +502,16 @@ out_cleanup: + printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); + } + ++static bool radeon_test_sync_possible(struct radeon_ring *ringA, ++ struct radeon_ring *ringB) ++{ ++ if (ringA->idx == TN_RING_TYPE_VCE2_INDEX && ++ ringB->idx == TN_RING_TYPE_VCE1_INDEX) ++ return false; ++ ++ return true; ++} ++ + void radeon_test_syncing(struct radeon_device *rdev) + { + int i, j, k; +@@ -500,6 +526,9 @@ void radeon_test_syncing(struct radeon_device *rdev) + if (!ringB->ready) + continue; + ++ if (!radeon_test_sync_possible(ringA, ringB)) ++ continue; ++ + DRM_INFO("Testing syncing between rings %d and %d...\n", i, j); + radeon_test_ring_sync(rdev, ringA, ringB); + +@@ -511,6 +540,12 @@ void radeon_test_syncing(struct radeon_device *rdev) + if (!ringC->ready) + continue; + ++ if (!radeon_test_sync_possible(ringA, ringC)) ++ continue; ++ ++ if (!radeon_test_sync_possible(ringB, ringC)) ++ continue; ++ + DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, j, k); + radeon_test_ring_sync2(rdev, ringA, ringB, ringC); + +diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c +new file mode 100644 +index 0000000..2547d8e +--- /dev/null ++++ b/drivers/gpu/drm/radeon/radeon_vce.c +@@ -0,0 +1,588 @@ ++/* ++ * Copyright 2013 Advanced Micro Devices, Inc. ++ * All Rights Reserved. ++ * ++ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * Authors: Christian König <christian.koenig@amd.com> ++ */ ++ ++#include <linux/firmware.h> ++#include <linux/module.h> ++#include <drm/drmP.h> ++#include <drm/drm.h> ++ ++#include "radeon.h" ++#include "radeon_asic.h" ++#include "sid.h" ++ ++/* Firmware Names */ ++#define FIRMWARE_BONAIRE "radeon/BONAIRE_vce.bin" ++ ++MODULE_FIRMWARE(FIRMWARE_BONAIRE); ++ ++/** ++ * radeon_vce_init - allocate memory, load vce firmware ++ * ++ * @rdev: radeon_device pointer ++ * ++ * First step to get VCE online, allocate memory and load the firmware ++ */ ++int radeon_vce_init(struct radeon_device *rdev) ++{ ++ unsigned long bo_size; ++ const char *fw_name; ++ int i, r; ++ ++ switch (rdev->family) { ++ case CHIP_BONAIRE: ++ case CHIP_KAVERI: ++ case CHIP_KABINI: ++ fw_name = FIRMWARE_BONAIRE; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ r = request_firmware(&rdev->vce_fw, fw_name, rdev->dev); ++ if (r) { ++ dev_err(rdev->dev, "radeon_vce: Can't load firmware \"%s\"\n", ++ fw_name); ++ return r; ++ } ++ ++ bo_size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) + ++ RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE; ++ r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, ++ RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->vce.vcpu_bo); ++ if (r) { ++ dev_err(rdev->dev, "(%d) failed to allocate VCE bo\n", r); ++ return r; ++ } ++ ++ r = radeon_vce_resume(rdev); ++ if (r) ++ return r; ++ ++ memset(rdev->vce.cpu_addr, 0, bo_size); ++ memcpy(rdev->vce.cpu_addr, rdev->vce_fw->data, rdev->vce_fw->size); ++ ++ r = radeon_vce_suspend(rdev); ++ if (r) ++ return r; ++ ++ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { ++ atomic_set(&rdev->vce.handles[i], 0); ++ rdev->vce.filp[i] = NULL; ++ } ++ ++ return 0; ++} ++ ++/** ++ * radeon_vce_fini - free memory ++ * ++ * @rdev: radeon_device pointer ++ * ++ * Last step on VCE teardown, free firmware memory ++ */ ++void radeon_vce_fini(struct radeon_device *rdev) ++{ ++ radeon_vce_suspend(rdev); ++ radeon_bo_unref(&rdev->vce.vcpu_bo); ++} ++ ++/** ++ * radeon_vce_suspend - unpin VCE fw memory ++ * ++ * @rdev: radeon_device pointer ++ * ++ * TODO: Test VCE suspend/resume ++ */ ++int radeon_vce_suspend(struct radeon_device *rdev) ++{ ++ int r; ++ ++ if (rdev->vce.vcpu_bo == NULL) ++ return 0; ++ ++ r = radeon_bo_reserve(rdev->vce.vcpu_bo, false); ++ if (!r) { ++ radeon_bo_kunmap(rdev->vce.vcpu_bo); ++ radeon_bo_unpin(rdev->vce.vcpu_bo); ++ radeon_bo_unreserve(rdev->vce.vcpu_bo); ++ } ++ return r; ++} ++ ++/** ++ * radeon_vce_resume - pin VCE fw memory ++ * ++ * @rdev: radeon_device pointer ++ * ++ * TODO: Test VCE suspend/resume ++ */ ++int radeon_vce_resume(struct radeon_device *rdev) ++{ ++ int r; ++ ++ if (rdev->vce.vcpu_bo == NULL) ++ return -EINVAL; ++ ++ r = radeon_bo_reserve(rdev->vce.vcpu_bo, false); ++ if (r) { ++ radeon_bo_unref(&rdev->vce.vcpu_bo); ++ dev_err(rdev->dev, "(%d) failed to reserve VCE bo\n", r); ++ return r; ++ } ++ ++ r = radeon_bo_pin(rdev->vce.vcpu_bo, RADEON_GEM_DOMAIN_VRAM, ++ &rdev->vce.gpu_addr); ++ if (r) { ++ radeon_bo_unreserve(rdev->vce.vcpu_bo); ++ radeon_bo_unref(&rdev->vce.vcpu_bo); ++ dev_err(rdev->dev, "(%d) VCE bo pin failed\n", r); ++ return r; ++ } ++ ++ r = radeon_bo_kmap(rdev->vce.vcpu_bo, &rdev->vce.cpu_addr); ++ if (r) { ++ dev_err(rdev->dev, "(%d) VCE map failed\n", r); ++ return r; ++ } ++ ++ radeon_bo_unreserve(rdev->vce.vcpu_bo); ++ ++ return 0; ++} ++ ++/** ++ * radeon_vce_free_handles - free still open VCE handles ++ * ++ * @rdev: radeon_device pointer ++ * @filp: drm file pointer ++ * ++ * Close all VCE handles still open by this file pointer ++ */ ++void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp) ++{ ++ int i, r; ++ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { ++ uint32_t handle = atomic_read(&rdev->vce.handles[i]); ++ if (!handle || rdev->vce.filp[i] != filp) ++ continue; ++ ++ r = radeon_vce_get_destroy_msg(rdev, TN_RING_TYPE_VCE1_INDEX, ++ handle, NULL); ++ if (r) ++ DRM_ERROR("Error destroying VCE handle (%d)!\n", r); ++ ++ rdev->vce.filp[i] = NULL; ++ atomic_set(&rdev->vce.handles[i], 0); ++ } ++} ++ ++/** ++ * radeon_vce_get_create_msg - generate a VCE create msg ++ * ++ * @rdev: radeon_device pointer ++ * @ring: ring we should submit the msg to ++ * @handle: VCE session handle to use ++ * @fence: optional fence to return ++ * ++ * Open up a stream for HW test ++ */ ++int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring, ++ uint32_t handle, struct radeon_fence **fence) ++{ ++ const unsigned ib_size_dw = 1024; ++ struct radeon_ib ib; ++ uint64_t dummy; ++ int i, r; ++ ++ r = radeon_ib_get(rdev, ring, &ib, NULL, ib_size_dw * 4); ++ if (r) { ++ DRM_ERROR("radeon: failed to get ib (%d).\n", r); ++ return r; ++ } ++ ++ dummy = ib.gpu_addr + 1024; ++ ++ /* stitch together an VCE create msg */ ++ ib.length_dw = 0; ++ ib.ptr[ib.length_dw++] = 0x0000000c; /* len */ ++ ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */ ++ ib.ptr[ib.length_dw++] = handle; ++ ++ ib.ptr[ib.length_dw++] = 0x00000030; /* len */ ++ ib.ptr[ib.length_dw++] = 0x01000001; /* create cmd */ ++ ib.ptr[ib.length_dw++] = 0x00000000; ++ ib.ptr[ib.length_dw++] = 0x00000042; ++ ib.ptr[ib.length_dw++] = 0x0000000a; ++ ib.ptr[ib.length_dw++] = 0x00000001; ++ ib.ptr[ib.length_dw++] = 0x00000080; ++ ib.ptr[ib.length_dw++] = 0x00000060; ++ ib.ptr[ib.length_dw++] = 0x00000100; ++ ib.ptr[ib.length_dw++] = 0x00000100; ++ ib.ptr[ib.length_dw++] = 0x0000000c; ++ ib.ptr[ib.length_dw++] = 0x00000000; ++ ++ ib.ptr[ib.length_dw++] = 0x00000014; /* len */ ++ ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */ ++ ib.ptr[ib.length_dw++] = upper_32_bits(dummy); ++ ib.ptr[ib.length_dw++] = dummy; ++ ib.ptr[ib.length_dw++] = 0x00000001; ++ ++ for (i = ib.length_dw; i < ib_size_dw; ++i) ++ ib.ptr[i] = 0x0; ++ ++ r = radeon_ib_schedule(rdev, &ib, NULL); ++ if (r) { ++ DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); ++ } ++ ++ if (fence) ++ *fence = radeon_fence_ref(ib.fence); ++ ++ radeon_ib_free(rdev, &ib); ++ ++ return r; ++} ++ ++/** ++ * radeon_vce_get_destroy_msg - generate a VCE destroy msg ++ * ++ * @rdev: radeon_device pointer ++ * @ring: ring we should submit the msg to ++ * @handle: VCE session handle to use ++ * @fence: optional fence to return ++ * ++ * Close up a stream for HW test or if userspace failed to do so ++ */ ++int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring, ++ uint32_t handle, struct radeon_fence **fence) ++{ ++ const unsigned ib_size_dw = 1024; ++ struct radeon_ib ib; ++ uint64_t dummy; ++ int i, r; ++ ++ r = radeon_ib_get(rdev, ring, &ib, NULL, ib_size_dw * 4); ++ if (r) { ++ DRM_ERROR("radeon: failed to get ib (%d).\n", r); ++ return r; ++ } ++ ++ dummy = ib.gpu_addr + 1024; ++ ++ /* stitch together an VCE destroy msg */ ++ ib.length_dw = 0; ++ ib.ptr[ib.length_dw++] = 0x0000000c; /* len */ ++ ib.ptr[ib.length_dw++] = 0x00000001; /* session cmd */ ++ ib.ptr[ib.length_dw++] = handle; ++ ++ ib.ptr[ib.length_dw++] = 0x00000014; /* len */ ++ ib.ptr[ib.length_dw++] = 0x05000005; /* feedback buffer */ ++ ib.ptr[ib.length_dw++] = upper_32_bits(dummy); ++ ib.ptr[ib.length_dw++] = dummy; ++ ib.ptr[ib.length_dw++] = 0x00000001; ++ ++ ib.ptr[ib.length_dw++] = 0x00000008; /* len */ ++ ib.ptr[ib.length_dw++] = 0x02000001; /* destroy cmd */ ++ ++ for (i = ib.length_dw; i < ib_size_dw; ++i) ++ ib.ptr[i] = 0x0; ++ ++ r = radeon_ib_schedule(rdev, &ib, NULL); ++ if (r) { ++ DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); ++ } ++ ++ if (fence) ++ *fence = radeon_fence_ref(ib.fence); ++ ++ radeon_ib_free(rdev, &ib); ++ ++ return r; ++} ++ ++/** ++ * radeon_vce_cs_reloc - command submission relocation ++ * ++ * @p: parser context ++ * @lo: address of lower dword ++ * @hi: address of higher dword ++ * ++ * Patch relocation inside command stream with real buffer address ++ */ ++int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi) ++{ ++ struct radeon_cs_chunk *relocs_chunk; ++ uint64_t offset; ++ unsigned idx; ++ ++ relocs_chunk = &p->chunks[p->chunk_relocs_idx]; ++ offset = radeon_get_ib_value(p, lo); ++ idx = radeon_get_ib_value(p, hi); ++ ++ if (idx >= relocs_chunk->length_dw) { ++ DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", ++ idx, relocs_chunk->length_dw); ++ return -EINVAL; ++ } ++ ++ offset += p->relocs_ptr[(idx / 4)]->lobj.gpu_offset; ++ ++ p->ib.ptr[lo] = offset & 0xFFFFFFFF; ++ p->ib.ptr[hi] = offset >> 32; ++ ++ return 0; ++} ++ ++/** ++ * radeon_vce_cs_parse - parse and validate the command stream ++ * ++ * @p: parser context ++ * ++ */ ++int radeon_vce_cs_parse(struct radeon_cs_parser *p) ++{ ++ uint32_t handle = 0; ++ bool destroy = false; ++ int i, r; ++ ++ while (p->idx < p->chunks[p->chunk_ib_idx].length_dw) { ++ uint32_t len = radeon_get_ib_value(p, p->idx); ++ uint32_t cmd = radeon_get_ib_value(p, p->idx + 1); ++ ++ if ((len < 8) || (len & 3)) { ++ DRM_ERROR("invalid VCE command length (%d)!\n", len); ++ return -EINVAL; ++ } ++ ++ switch (cmd) { ++ case 0x00000001: // session ++ handle = radeon_get_ib_value(p, p->idx + 2); ++ break; ++ ++ case 0x00000002: // task info ++ case 0x01000001: // create ++ case 0x04000001: // config extension ++ case 0x04000002: // pic control ++ case 0x04000005: // rate control ++ case 0x04000007: // motion estimation ++ case 0x04000008: // rdo ++ break; ++ ++ case 0x03000001: // encode ++ r = radeon_vce_cs_reloc(p, p->idx + 10, p->idx + 9); ++ if (r) ++ return r; ++ ++ r = radeon_vce_cs_reloc(p, p->idx + 12, p->idx + 11); ++ if (r) ++ return r; ++ break; ++ ++ case 0x02000001: // destroy ++ destroy = true; ++ break; ++ ++ case 0x05000001: // context buffer ++ case 0x05000004: // video bitstream buffer ++ case 0x05000005: // feedback buffer ++ r = radeon_vce_cs_reloc(p, p->idx + 3, p->idx + 2); ++ if (r) ++ return r; ++ break; ++ ++ default: ++ DRM_ERROR("invalid VCE command (0x%x)!\n", cmd); ++ return -EINVAL; ++ } ++ ++ p->idx += len / 4; ++ } ++ ++ if (destroy) { ++ /* IB contains a destroy msg, free the handle */ ++ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) ++ atomic_cmpxchg(&p->rdev->vce.handles[i], handle, 0); ++ ++ return 0; ++ } ++ ++ /* create or encode, validate the handle */ ++ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { ++ if (atomic_read(&p->rdev->vce.handles[i]) == handle) ++ return 0; ++ } ++ ++ /* handle not found try to alloc a new one */ ++ for (i = 0; i < RADEON_MAX_VCE_HANDLES; ++i) { ++ if (!atomic_cmpxchg(&p->rdev->vce.handles[i], 0, handle)) { ++ p->rdev->vce.filp[i] = p->filp; ++ return 0; ++ } ++ } ++ ++ DRM_ERROR("No more free VCE handles!\n"); ++ return -EINVAL; ++} ++ ++/** ++ * radeon_vce_semaphore_emit - emit a semaphore command ++ * ++ * @rdev: radeon_device pointer ++ * @ring: engine to use ++ * @semaphore: address of semaphore ++ * @emit_wait: true=emit wait, false=emit signal ++ * ++ */ ++bool radeon_vce_semaphore_emit(struct radeon_device *rdev, ++ struct radeon_ring *ring, ++ struct radeon_semaphore *semaphore, ++ bool emit_wait) ++{ ++ uint64_t addr = semaphore->gpu_addr; ++ ++ radeon_ring_write(ring, VCE_CMD_SEMAPHORE); ++ radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); ++ radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); ++ radeon_ring_write(ring, 0x01003000 | (emit_wait ? 1 : 0)); ++ if (!emit_wait) ++ radeon_ring_write(ring, VCE_CMD_END); ++ ++ return true; ++} ++ ++/** ++ * radeon_vce_ib_execute - execute indirect buffer ++ * ++ * @rdev: radeon_device pointer ++ * @ib: the IB to execute ++ * ++ */ ++void radeon_vce_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) ++{ ++ struct radeon_ring *ring = &rdev->ring[ib->ring]; ++ radeon_ring_write(ring, VCE_CMD_IB); ++ radeon_ring_write(ring, ib->gpu_addr); ++ radeon_ring_write(ring, upper_32_bits(ib->gpu_addr)); ++ radeon_ring_write(ring, ib->length_dw); ++} ++ ++/** ++ * radeon_vce_fence_emit - add a fence command to the ring ++ * ++ * @rdev: radeon_device pointer ++ * @fence: the fence ++ * ++ */ ++void radeon_vce_fence_emit(struct radeon_device *rdev, ++ struct radeon_fence *fence) ++{ ++ struct radeon_ring *ring = &rdev->ring[fence->ring]; ++ uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr; ++ ++ radeon_ring_write(ring, VCE_CMD_FENCE); ++ radeon_ring_write(ring, addr); ++ radeon_ring_write(ring, upper_32_bits(addr)); ++ radeon_ring_write(ring, fence->seq); ++ radeon_ring_write(ring, VCE_CMD_TRAP); ++ radeon_ring_write(ring, VCE_CMD_END); ++} ++ ++/** ++ * radeon_vce_ring_test - test if VCE ring is working ++ * ++ * @rdev: radeon_device pointer ++ * @ring: the engine to test on ++ * ++ */ ++int radeon_vce_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) ++{ ++ uint32_t rptr = vce_v1_0_get_rptr(rdev, ring); ++ unsigned i; ++ int r; ++ ++ r = radeon_ring_lock(rdev, ring, 16); ++ if (r) { ++ DRM_ERROR("radeon: vce failed to lock ring %d (%d).\n", ++ ring->idx, r); ++ return r; ++ } ++ radeon_ring_write(ring, VCE_CMD_END); ++ radeon_ring_unlock_commit(rdev, ring); ++ ++ for (i = 0; i < rdev->usec_timeout; i++) { ++ if (vce_v1_0_get_rptr(rdev, ring) != rptr) ++ break; ++ DRM_UDELAY(1); ++ } ++ ++ if (i < rdev->usec_timeout) { ++ DRM_INFO("ring test on %d succeeded in %d usecs\n", ++ ring->idx, i); ++ } else { ++ DRM_ERROR("radeon: ring %d test failed\n", ++ ring->idx); ++ r = -ETIMEDOUT; ++ } ++ ++ return r; ++} ++ ++/** ++ * radeon_vce_ib_test - test if VCE IBs are working ++ * ++ * @rdev: radeon_device pointer ++ * @ring: the engine to test on ++ * ++ */ ++int radeon_vce_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) ++{ ++ struct radeon_fence *fence = NULL; ++ int r; ++ ++ r = radeon_vce_get_create_msg(rdev, ring->idx, 1, NULL); ++ if (r) { ++ DRM_ERROR("radeon: failed to get create msg (%d).\n", r); ++ goto error; ++ } ++ ++ r = radeon_vce_get_destroy_msg(rdev, ring->idx, 1, &fence); ++ if (r) { ++ DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r); ++ goto error; ++ } ++ ++ r = radeon_fence_wait(fence, false); ++ if (r) { ++ DRM_ERROR("radeon: fence wait failed (%d).\n", r); ++ } else { ++ DRM_INFO("ib test on ring %d succeeded\n", ring->idx); ++ } ++error: ++ radeon_fence_unref(&fence); ++ return r; ++} +diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h +index db3dd87..1da5a7a 100644 +--- a/drivers/gpu/drm/radeon/sid.h ++++ b/drivers/gpu/drm/radeon/sid.h +@@ -1747,4 +1747,51 @@ + #define DMA_PACKET_CONSTANT_FILL 0xd + #define DMA_PACKET_NOP 0xf + ++#define VCE_STATUS 0x20004 ++#define VCE_VCPU_CNTL 0x20014 ++#define VCE_CLK_EN (1 << 0) ++#define VCE_VCPU_CACHE_OFFSET0 0x20024 ++#define VCE_VCPU_CACHE_SIZE0 0x20028 ++#define VCE_VCPU_CACHE_OFFSET1 0x2002c ++#define VCE_VCPU_CACHE_SIZE1 0x20030 ++#define VCE_VCPU_CACHE_OFFSET2 0x20034 ++#define VCE_VCPU_CACHE_SIZE2 0x20038 ++#define VCE_SOFT_RESET 0x20120 ++#define VCE_ECPU_SOFT_RESET (1 << 0) ++#define VCE_FME_SOFT_RESET (1 << 2) ++#define VCE_RB_BASE_LO2 0x2016c ++#define VCE_RB_BASE_HI2 0x20170 ++#define VCE_RB_SIZE2 0x20174 ++#define VCE_RB_RPTR2 0x20178 ++#define VCE_RB_WPTR2 0x2017c ++#define VCE_RB_BASE_LO 0x20180 ++#define VCE_RB_BASE_HI 0x20184 ++#define VCE_RB_SIZE 0x20188 ++#define VCE_RB_RPTR 0x2018c ++#define VCE_RB_WPTR 0x20190 ++#define VCE_CLOCK_GATING_A 0x202f8 ++#define VCE_CLOCK_GATING_B 0x202fc ++#define VCE_UENC_CLOCK_GATING 0x205bc ++#define VCE_UENC_REG_CLOCK_GATING 0x205c0 ++#define VCE_FW_REG_STATUS 0x20e10 ++# define VCE_FW_REG_STATUS_BUSY (1 << 0) ++# define VCE_FW_REG_STATUS_PASS (1 << 3) ++# define VCE_FW_REG_STATUS_DONE (1 << 11) ++#define VCE_LMI_FW_START_KEYSEL 0x20e18 ++#define VCE_LMI_FW_PERIODIC_CTRL 0x20e20 ++#define VCE_LMI_CTRL2 0x20e74 ++#define VCE_LMI_CTRL 0x20e98 ++#define VCE_LMI_VM_CTRL 0x20ea0 ++#define VCE_LMI_SWAP_CNTL 0x20eb4 ++#define VCE_LMI_SWAP_CNTL1 0x20eb8 ++#define VCE_LMI_CACHE_CTRL 0x20ef4 ++ ++#define VCE_CMD_NO_OP 0x00000000 ++#define VCE_CMD_END 0x00000001 ++#define VCE_CMD_IB 0x00000002 ++#define VCE_CMD_FENCE 0x00000003 ++#define VCE_CMD_TRAP 0x00000004 ++#define VCE_CMD_IB_AUTO 0x00000005 ++#define VCE_CMD_SEMAPHORE 0x00000006 ++ + #endif +diff --git a/drivers/gpu/drm/radeon/vce_v1_0.c b/drivers/gpu/drm/radeon/vce_v1_0.c +new file mode 100644 +index 0000000..e0c3534 +--- /dev/null ++++ b/drivers/gpu/drm/radeon/vce_v1_0.c +@@ -0,0 +1,187 @@ ++/* ++ * Copyright 2013 Advanced Micro Devices, Inc. ++ * All Rights Reserved. ++ * ++ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * Authors: Christian König <christian.koenig@amd.com> ++ */ ++ ++#include <linux/firmware.h> ++#include <drm/drmP.h> ++#include "radeon.h" ++#include "radeon_asic.h" ++#include "sid.h" ++ ++/** ++ * vce_v1_0_get_rptr - get read pointer ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon_ring pointer ++ * ++ * Returns the current hardware read pointer ++ */ ++uint32_t vce_v1_0_get_rptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ if (ring->idx == TN_RING_TYPE_VCE1_INDEX) ++ return RREG32(VCE_RB_RPTR); ++ else ++ return RREG32(VCE_RB_RPTR2); ++} ++ ++/** ++ * vce_v1_0_get_wptr - get write pointer ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon_ring pointer ++ * ++ * Returns the current hardware write pointer ++ */ ++uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ if (ring->idx == TN_RING_TYPE_VCE1_INDEX) ++ return RREG32(VCE_RB_WPTR); ++ else ++ return RREG32(VCE_RB_WPTR2); ++} ++ ++/** ++ * vce_v1_0_set_wptr - set write pointer ++ * ++ * @rdev: radeon_device pointer ++ * @ring: radeon_ring pointer ++ * ++ * Commits the write pointer to the hardware ++ */ ++void vce_v1_0_set_wptr(struct radeon_device *rdev, ++ struct radeon_ring *ring) ++{ ++ if (ring->idx == TN_RING_TYPE_VCE1_INDEX) ++ WREG32(VCE_RB_WPTR, ring->wptr); ++ else ++ WREG32(VCE_RB_WPTR2, ring->wptr); ++} ++ ++/** ++ * vce_v1_0_start - start VCE block ++ * ++ * @rdev: radeon_device pointer ++ * ++ * Setup and start the VCE block ++ */ ++int vce_v1_0_start(struct radeon_device *rdev) ++{ ++ struct radeon_ring *ring; ++ int i, j, r; ++ ++ /* set BUSY flag */ ++ WREG32_P(VCE_STATUS, 1, ~1); ++ ++ ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; ++ WREG32(VCE_RB_RPTR, ring->rptr); ++ WREG32(VCE_RB_WPTR, ring->wptr); ++ WREG32(VCE_RB_BASE_LO, ring->gpu_addr); ++ WREG32(VCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); ++ WREG32(VCE_RB_SIZE, ring->ring_size / 4); ++ ++ ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; ++ WREG32(VCE_RB_RPTR2, ring->rptr); ++ WREG32(VCE_RB_WPTR2, ring->wptr); ++ WREG32(VCE_RB_BASE_LO2, ring->gpu_addr); ++ WREG32(VCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); ++ WREG32(VCE_RB_SIZE2, ring->ring_size / 4); ++ ++ WREG32_P(VCE_VCPU_CNTL, VCE_CLK_EN, ~VCE_CLK_EN); ++ ++ WREG32_P(VCE_SOFT_RESET, ++ VCE_ECPU_SOFT_RESET | ++ VCE_FME_SOFT_RESET, ~( ++ VCE_ECPU_SOFT_RESET | ++ VCE_FME_SOFT_RESET)); ++ ++ mdelay(100); ++ ++ WREG32_P(VCE_SOFT_RESET, 0, ~( ++ VCE_ECPU_SOFT_RESET | ++ VCE_FME_SOFT_RESET)); ++ ++ for (i = 0; i < 10; ++i) { ++ uint32_t status; ++ for (j = 0; j < 100; ++j) { ++ status = RREG32(VCE_STATUS); ++ if (status & 2) ++ break; ++ mdelay(10); ++ } ++ r = 0; ++ if (status & 2) ++ break; ++ ++ DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); ++ WREG32_P(VCE_SOFT_RESET, VCE_ECPU_SOFT_RESET, ~VCE_ECPU_SOFT_RESET); ++ mdelay(10); ++ WREG32_P(VCE_SOFT_RESET, 0, ~VCE_ECPU_SOFT_RESET); ++ mdelay(10); ++ r = -1; ++ } ++ ++ /* clear BUSY flag */ ++ WREG32_P(VCE_STATUS, 0, ~1); ++ ++ if (r) { ++ DRM_ERROR("VCE not responding, giving up!!!\n"); ++ return r; ++ } ++ ++ return 0; ++} ++ ++int vce_v1_0_init(struct radeon_device *rdev) ++{ ++ struct radeon_ring *ring; ++ int r; ++ ++ r = vce_v1_0_start(rdev); ++ if (r) ++ return r; ++ ++ ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; ++ ring->ready = true; ++ r = radeon_ring_test(rdev, TN_RING_TYPE_VCE1_INDEX, ring); ++ if (r) { ++ ring->ready = false; ++ return r; ++ } ++ ++ ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; ++ ring->ready = true; ++ r = radeon_ring_test(rdev, TN_RING_TYPE_VCE2_INDEX, ring); ++ if (r) { ++ ring->ready = false; ++ return r; ++ } ++ ++ DRM_INFO("VCE initialized successfully.\n"); ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/radeon/vce_v2_0.c b/drivers/gpu/drm/radeon/vce_v2_0.c +new file mode 100644 +index 0000000..4911d1b +--- /dev/null ++++ b/drivers/gpu/drm/radeon/vce_v2_0.c +@@ -0,0 +1,70 @@ ++/* ++ * Copyright 2013 Advanced Micro Devices, Inc. ++ * All Rights Reserved. ++ * ++ * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * Authors: Christian König <christian.koenig@amd.com> ++ */ ++ ++#include <linux/firmware.h> ++#include <drm/drmP.h> ++#include "radeon.h" ++#include "radeon_asic.h" ++#include "cikd.h" ++ ++int vce_v2_0_resume(struct radeon_device *rdev) ++{ ++ uint64_t addr = rdev->vce.gpu_addr; ++ uint32_t size; ++ ++ WREG32_P(VCE_CLOCK_GATING_A, 0, ~(1 << 16)); ++ WREG32_P(VCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000); ++ WREG32_P(VCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F); ++ WREG32(VCE_CLOCK_GATING_B, 0xf7); ++ ++ WREG32(VCE_LMI_CTRL, 0x00398000); ++ WREG32_P(VCE_LMI_CACHE_CTRL, 0x0, ~0x1); ++ WREG32(VCE_LMI_SWAP_CNTL, 0); ++ WREG32(VCE_LMI_SWAP_CNTL1, 0); ++ WREG32(VCE_LMI_VM_CTRL, 0); ++ ++ size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size); ++ WREG32(VCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff); ++ WREG32(VCE_VCPU_CACHE_SIZE0, size); ++ ++ addr += size; ++ size = RADEON_VCE_STACK_SIZE; ++ WREG32(VCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff); ++ WREG32(VCE_VCPU_CACHE_SIZE1, size); ++ ++ addr += size; ++ size = RADEON_VCE_HEAP_SIZE; ++ WREG32(VCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff); ++ WREG32(VCE_VCPU_CACHE_SIZE2, size); ++ ++ WREG32_P(VCE_LMI_CTRL2, 0x0, ~0x100); ++ ++ WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, ++ ~VCE_SYS_INT_TRAP_INTERRUPT_EN); ++ ++ return 0; ++} +diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h +index fe421e8..b93c92a 100644 +--- a/include/uapi/drm/radeon_drm.h ++++ b/include/uapi/drm/radeon_drm.h +@@ -919,6 +919,7 @@ struct drm_radeon_gem_va { + #define RADEON_CS_RING_COMPUTE 1 + #define RADEON_CS_RING_DMA 2 + #define RADEON_CS_RING_UVD 3 ++#define RADEON_CS_RING_VCE 4 + /* The third dword of RADEON_CHUNK_ID_FLAGS is a sint32 that sets the priority */ + /* 0 = normal, + = higher priority, - = lower priority */ + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0028-yocto-amd-drm-radeon-add-VCE-ring-query.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0028-yocto-amd-drm-radeon-add-VCE-ring-query.patch new file mode 100644 index 00000000..f68e0058 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0028-yocto-amd-drm-radeon-add-VCE-ring-query.patch @@ -0,0 +1,30 @@ +From dbc2d98551a2f32b8e7ad375ccc6b18bb8ef9709 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Mon, 27 Jan 2014 10:16:06 -0700 +Subject: [PATCH 28/44] drm/radeon: add VCE ring query +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon_kms.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +index 07da88f..c9dd7ef 100644 +--- a/drivers/gpu/drm/radeon/radeon_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_kms.c +@@ -417,6 +417,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) + case RADEON_CS_RING_UVD: + *value = rdev->ring[R600_RING_TYPE_UVD_INDEX].ready; + break; ++ case RADEON_CS_RING_VCE: ++ *value = rdev->ring[TN_RING_TYPE_VCE1_INDEX].ready; ++ break; + default: + return -EINVAL; + } +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0029-yocto-amd-drm-radeon-add-VCE-version-parsing-and-checking.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0029-yocto-amd-drm-radeon-add-VCE-version-parsing-and-checking.patch new file mode 100644 index 00000000..1f11b462 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0029-yocto-amd-drm-radeon-add-VCE-version-parsing-and-checking.patch @@ -0,0 +1,147 @@ +From 511a68ce32e94aa20be2ed70b3eccb059aef87bb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 23 Jan 2014 09:50:49 -0700 +Subject: [PATCH 29/44] drm/radeon: add VCE version parsing and checking +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Also make the result available to userspace. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 2 ++ + drivers/gpu/drm/radeon/radeon_kms.c | 6 ++++ + drivers/gpu/drm/radeon/radeon_vce.c | 56 +++++++++++++++++++++++++++++++---- + include/uapi/drm/radeon_drm.h | 4 +++ + 4 files changed, 62 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 094e5f5..6abe303 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -1601,6 +1601,8 @@ struct radeon_vce { + struct radeon_bo *vcpu_bo; + void *cpu_addr; + uint64_t gpu_addr; ++ unsigned fw_version; ++ unsigned fb_version; + atomic_t handles[RADEON_MAX_VCE_HANDLES]; + struct drm_file *filp[RADEON_MAX_VCE_HANDLES]; + }; +diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +index c9dd7ef..cc2d29d 100644 +--- a/drivers/gpu/drm/radeon/radeon_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_kms.c +@@ -457,6 +457,12 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) + DRM_DEBUG_KMS("BACKEND_ENABLED_MASK is si+ only!\n"); + } + break; ++ case RADEON_INFO_VCE_FW_VERSION: ++ *value = rdev->vce.fw_version; ++ break; ++ case RADEON_INFO_VCE_FB_VERSION: ++ *value = rdev->vce.fb_version; ++ break; + default: + DRM_DEBUG_KMS("Invalid request %d\n", info->request); + return -EINVAL; +diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c +index 2547d8e..f46563b 100644 +--- a/drivers/gpu/drm/radeon/radeon_vce.c ++++ b/drivers/gpu/drm/radeon/radeon_vce.c +@@ -48,8 +48,11 @@ MODULE_FIRMWARE(FIRMWARE_BONAIRE); + */ + int radeon_vce_init(struct radeon_device *rdev) + { +- unsigned long bo_size; +- const char *fw_name; ++ static const char *fw_version = "[ATI LIB=VCEFW,"; ++ static const char *fb_version = "[ATI LIB=VCEFWSTATS,"; ++ unsigned long size; ++ const char *fw_name, *c; ++ uint8_t start, mid, end; + int i, r; + + switch (rdev->family) { +@@ -70,9 +73,50 @@ int radeon_vce_init(struct radeon_device *rdev) + return r; + } + +- bo_size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) + +- RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE; +- r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, ++ /* search for firmware version */ ++ ++ size = rdev->vce_fw->size - strlen(fw_version) - 9; ++ c = rdev->vce_fw->data; ++ for (;size > 0; --size, ++c) ++ if (strncmp(c, fw_version, strlen(fw_version)) == 0) ++ break; ++ ++ if (size == 0) ++ return -EINVAL; ++ ++ c += strlen(fw_version); ++ if (sscanf(c, "%2hhd.%2hhd.%2hhd]", &start, &mid, &end) != 3) ++ return -EINVAL; ++ ++ /* search for feedback version */ ++ ++ size = rdev->vce_fw->size - strlen(fb_version) - 3; ++ c = rdev->vce_fw->data; ++ for (;size > 0; --size, ++c) ++ if (strncmp(c, fb_version, strlen(fb_version)) == 0) ++ break; ++ ++ if (size == 0) ++ return -EINVAL; ++ ++ c += strlen(fb_version); ++ if (sscanf(c, "%2u]", &rdev->vce.fb_version) != 1) ++ return -EINVAL; ++ ++ DRM_INFO("Found VCE firmware/feedback version %hhd.%hhd.%hhd / %d!\n", ++ start, mid, end, rdev->vce.fb_version); ++ ++ rdev->vce.fw_version = (start << 24) | (mid << 16) | (end << 8); ++ ++ /* we can only work with this fw version for now */ ++ if (rdev->vce.fw_version != ((40 << 24) | (2 << 16) | (2 << 8))) ++ return -EINVAL; ++ ++ /* load firmware into VRAM */ ++ ++ size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) + ++ RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE; ++ r = radeon_bo_create(rdev, size, PAGE_SIZE, true, + RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->vce.vcpu_bo); + if (r) { + dev_err(rdev->dev, "(%d) failed to allocate VCE bo\n", r); +@@ -83,7 +127,7 @@ int radeon_vce_init(struct radeon_device *rdev) + if (r) + return r; + +- memset(rdev->vce.cpu_addr, 0, bo_size); ++ memset(rdev->vce.cpu_addr, 0, size); + memcpy(rdev->vce.cpu_addr, rdev->vce_fw->data, rdev->vce_fw->size); + + r = radeon_vce_suspend(rdev); +diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h +index b93c92a..2ff6e71 100644 +--- a/include/uapi/drm/radeon_drm.h ++++ b/include/uapi/drm/radeon_drm.h +@@ -986,6 +986,10 @@ struct drm_radeon_cs { + #define RADEON_INFO_CIK_MACROTILE_MODE_ARRAY 0x18 + /* query the number of render backends */ + #define RADEON_INFO_SI_BACKEND_ENABLED_MASK 0x19 ++/* version of VCE firmware */ ++#define RADEON_INFO_VCE_FW_VERSION 0x1b ++/* version of VCE feedback */ ++#define RADEON_INFO_VCE_FB_VERSION 0x1c + + + struct drm_radeon_info { +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0030-yocto-amd-drm-radeon-add-callback-for-setting-vce-clocks.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0030-yocto-amd-drm-radeon-add-callback-for-setting-vce-clocks.patch new file mode 100644 index 00000000..26edee67 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0030-yocto-amd-drm-radeon-add-callback-for-setting-vce-clocks.patch @@ -0,0 +1,35 @@ +From f6b00233428f66b0a57d6d9943c05eff10169f6b Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Tue, 20 Aug 2013 20:01:18 -0400 +Subject: [PATCH 30/44] drm/radeon: add callback for setting vce clocks + +Similar to uvd clock setting. + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 6abe303..f0ad724 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -1817,6 +1817,7 @@ struct radeon_asic { + void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); + void (*set_clock_gating)(struct radeon_device *rdev, int enable); + int (*set_uvd_clocks)(struct radeon_device *rdev, u32 vclk, u32 dclk); ++ int (*set_vce_clocks)(struct radeon_device *rdev, u32 evclk, u32 ecclk); + int (*get_temperature)(struct radeon_device *rdev); + } pm; + /* dynamic power management */ +@@ -2673,6 +2674,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); + #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->pm.set_pcie_lanes((rdev), (l)) + #define radeon_set_clock_gating(rdev, e) (rdev)->asic->pm.set_clock_gating((rdev), (e)) + #define radeon_set_uvd_clocks(rdev, v, d) (rdev)->asic->pm.set_uvd_clocks((rdev), (v), (d)) ++#define radeon_set_vce_clocks(rdev, ev, ec) (rdev)->asic->pm.set_vce_clocks((rdev), (ev), (ec)) + #define radeon_get_temperature(rdev) (rdev)->asic->pm.get_temperature((rdev)) + #define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->surface.set_reg((rdev), (r), (f), (p), (o), (s))) + #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->surface.clear_reg((rdev), (r))) +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0031-yocto-amd-drm-radeon-dpm-move-platform-caps-fetching-to-a-sepa.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0031-yocto-amd-drm-radeon-dpm-move-platform-caps-fetching-to-a-sepa.patch new file mode 100644 index 00000000..9dab9dcc --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0031-yocto-amd-drm-radeon-dpm-move-platform-caps-fetching-to-a-sepa.patch @@ -0,0 +1,330 @@ +From d57ea9870d87db49132b6cd8067d512fb2810e24 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Wed, 21 Aug 2013 10:02:32 -0400 +Subject: [PATCH 31/44] drm/radeon/dpm: move platform caps fetching to a + separate function + +It's needed by by both the asic specific functions and the +extended table parser. + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/btc_dpm.c | 4 ++++ + drivers/gpu/drm/radeon/ci_dpm.c | 9 ++++++--- + drivers/gpu/drm/radeon/cypress_dpm.c | 4 ++++ + drivers/gpu/drm/radeon/kv_dpm.c | 7 ++++--- + drivers/gpu/drm/radeon/ni_dpm.c | 7 ++++--- + drivers/gpu/drm/radeon/r600_dpm.c | 20 ++++++++++++++++++++ + drivers/gpu/drm/radeon/r600_dpm.h | 2 ++ + drivers/gpu/drm/radeon/rs780_dpm.c | 7 ++++--- + drivers/gpu/drm/radeon/rv6xx_dpm.c | 7 ++++--- + drivers/gpu/drm/radeon/rv770_dpm.c | 7 ++++--- + drivers/gpu/drm/radeon/si_dpm.c | 7 ++++--- + drivers/gpu/drm/radeon/sumo_dpm.c | 7 ++++--- + drivers/gpu/drm/radeon/trinity_dpm.c | 7 ++++--- + 13 files changed, 68 insertions(+), 27 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c +index 9b6950d..e910299 100644 +--- a/drivers/gpu/drm/radeon/btc_dpm.c ++++ b/drivers/gpu/drm/radeon/btc_dpm.c +@@ -2610,6 +2610,10 @@ int btc_dpm_init(struct radeon_device *rdev) + pi->min_vddc_in_table = 0; + pi->max_vddc_in_table = 0; + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = rv7xx_parse_power_table(rdev); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c +index 51e947a..b90834a 100644 +--- a/drivers/gpu/drm/radeon/ci_dpm.c ++++ b/drivers/gpu/drm/radeon/ci_dpm.c +@@ -4951,9 +4951,6 @@ static int ci_parse_power_table(struct radeon_device *rdev) + if (!rdev->pm.dpm.ps) + return -ENOMEM; + power_state_offset = (u8 *)state_array->states; +- rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); +- rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); +- rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); + for (i = 0; i < state_array->ucNumEntries; i++) { + u8 *idx; + power_state = (union pplib_power_state *)power_state_offset; +@@ -5069,6 +5066,12 @@ int ci_dpm_init(struct radeon_device *rdev) + ci_dpm_fini(rdev); + return ret; + } ++ ++ ret = r600_get_platform_caps(rdev); ++ if (ret) { ++ ci_dpm_fini(rdev); ++ return ret; ++ } + ret = ci_parse_power_table(rdev); + if (ret) { + ci_dpm_fini(rdev); +diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c +index 91bb470..db1f391 100644 +--- a/drivers/gpu/drm/radeon/cypress_dpm.c ++++ b/drivers/gpu/drm/radeon/cypress_dpm.c +@@ -2049,6 +2049,10 @@ int cypress_dpm_init(struct radeon_device *rdev) + pi->min_vddc_in_table = 0; + pi->max_vddc_in_table = 0; + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = rv7xx_parse_power_table(rdev); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c +index b419055..58b5a5d 100644 +--- a/drivers/gpu/drm/radeon/kv_dpm.c ++++ b/drivers/gpu/drm/radeon/kv_dpm.c +@@ -2556,9 +2556,6 @@ static int kv_parse_power_table(struct radeon_device *rdev) + if (!rdev->pm.dpm.ps) + return -ENOMEM; + power_state_offset = (u8 *)state_array->states; +- rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); +- rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); +- rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); + for (i = 0; i < state_array->ucNumEntries; i++) { + u8 *idx; + power_state = (union pplib_power_state *)power_state_offset; +@@ -2608,6 +2605,10 @@ int kv_dpm_init(struct radeon_device *rdev) + return -ENOMEM; + rdev->pm.dpm.priv = pi; + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = r600_parse_extended_power_table(rdev); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c +index f263390..76bcc1e 100644 +--- a/drivers/gpu/drm/radeon/ni_dpm.c ++++ b/drivers/gpu/drm/radeon/ni_dpm.c +@@ -4041,9 +4041,6 @@ static int ni_parse_power_table(struct radeon_device *rdev) + power_info->pplib.ucNumStates, GFP_KERNEL); + if (!rdev->pm.dpm.ps) + return -ENOMEM; +- rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); +- rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); +- rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); + + for (i = 0; i < power_info->pplib.ucNumStates; i++) { + power_state = (union pplib_power_state *) +@@ -4105,6 +4102,10 @@ int ni_dpm_init(struct radeon_device *rdev) + pi->min_vddc_in_table = 0; + pi->max_vddc_in_table = 0; + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = ni_parse_power_table(rdev); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c +index 5513d8f..d57cde7 100644 +--- a/drivers/gpu/drm/radeon/r600_dpm.c ++++ b/drivers/gpu/drm/radeon/r600_dpm.c +@@ -818,6 +818,26 @@ static int r600_parse_clk_voltage_dep_table(struct radeon_clock_voltage_dependen + return 0; + } + ++int r600_get_platform_caps(struct radeon_device *rdev) ++{ ++ struct radeon_mode_info *mode_info = &rdev->mode_info; ++ union power_info *power_info; ++ int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); ++ u16 data_offset; ++ u8 frev, crev; ++ ++ if (!atom_parse_data_header(mode_info->atom_context, index, NULL, ++ &frev, &crev, &data_offset)) ++ return -EINVAL; ++ power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); ++ ++ rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); ++ rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); ++ rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); ++ ++ return 0; ++} ++ + /* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */ + #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12 + #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14 +diff --git a/drivers/gpu/drm/radeon/r600_dpm.h b/drivers/gpu/drm/radeon/r600_dpm.h +index 1000bf9..7e5d2c2 100644 +--- a/drivers/gpu/drm/radeon/r600_dpm.h ++++ b/drivers/gpu/drm/radeon/r600_dpm.h +@@ -217,6 +217,8 @@ int r600_set_thermal_temperature_range(struct radeon_device *rdev, + int min_temp, int max_temp); + bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor); + ++int r600_get_platform_caps(struct radeon_device *rdev); ++ + int r600_parse_extended_power_table(struct radeon_device *rdev); + void r600_free_extended_power_table(struct radeon_device *rdev); + +diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c b/drivers/gpu/drm/radeon/rs780_dpm.c +index 6af8505..f3143c0 100644 +--- a/drivers/gpu/drm/radeon/rs780_dpm.c ++++ b/drivers/gpu/drm/radeon/rs780_dpm.c +@@ -815,9 +815,6 @@ static int rs780_parse_power_table(struct radeon_device *rdev) + power_info->pplib.ucNumStates, GFP_KERNEL); + if (!rdev->pm.dpm.ps) + return -ENOMEM; +- rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); +- rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); +- rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); + + for (i = 0; i < power_info->pplib.ucNumStates; i++) { + power_state = (union pplib_power_state *) +@@ -867,6 +864,10 @@ int rs780_dpm_init(struct radeon_device *rdev) + return -ENOMEM; + rdev->pm.dpm.priv = pi; + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = rs780_parse_power_table(rdev); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c +index 5811d27..3aa0a8c 100644 +--- a/drivers/gpu/drm/radeon/rv6xx_dpm.c ++++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c +@@ -1901,9 +1901,6 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev) + power_info->pplib.ucNumStates, GFP_KERNEL); + if (!rdev->pm.dpm.ps) + return -ENOMEM; +- rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); +- rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); +- rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); + + for (i = 0; i < power_info->pplib.ucNumStates; i++) { + power_state = (union pplib_power_state *) +@@ -1953,6 +1950,10 @@ int rv6xx_dpm_init(struct radeon_device *rdev) + return -ENOMEM; + rdev->pm.dpm.priv = pi; + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = rv6xx_parse_power_table(rdev); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c +index 374499d..4bcbacb 100644 +--- a/drivers/gpu/drm/radeon/rv770_dpm.c ++++ b/drivers/gpu/drm/radeon/rv770_dpm.c +@@ -2277,9 +2277,6 @@ int rv7xx_parse_power_table(struct radeon_device *rdev) + power_info->pplib.ucNumStates, GFP_KERNEL); + if (!rdev->pm.dpm.ps) + return -ENOMEM; +- rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); +- rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); +- rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); + + for (i = 0; i < power_info->pplib.ucNumStates; i++) { + power_state = (union pplib_power_state *) +@@ -2357,6 +2354,10 @@ int rv770_dpm_init(struct radeon_device *rdev) + pi->min_vddc_in_table = 0; + pi->max_vddc_in_table = 0; + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = rv7xx_parse_power_table(rdev); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c +index 2332aa1..749c45c 100644 +--- a/drivers/gpu/drm/radeon/si_dpm.c ++++ b/drivers/gpu/drm/radeon/si_dpm.c +@@ -6291,9 +6291,6 @@ static int si_parse_power_table(struct radeon_device *rdev) + if (!rdev->pm.dpm.ps) + return -ENOMEM; + power_state_offset = (u8 *)state_array->states; +- rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); +- rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); +- rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); + for (i = 0; i < state_array->ucNumEntries; i++) { + u8 *idx; + power_state = (union pplib_power_state *)power_state_offset; +@@ -6370,6 +6367,10 @@ int si_dpm_init(struct radeon_device *rdev) + pi->min_vddc_in_table = 0; + pi->max_vddc_in_table = 0; + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = si_parse_power_table(rdev); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c +index 96ea6db8..485d006 100644 +--- a/drivers/gpu/drm/radeon/sumo_dpm.c ++++ b/drivers/gpu/drm/radeon/sumo_dpm.c +@@ -1477,9 +1477,6 @@ static int sumo_parse_power_table(struct radeon_device *rdev) + if (!rdev->pm.dpm.ps) + return -ENOMEM; + power_state_offset = (u8 *)state_array->states; +- rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); +- rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); +- rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); + for (i = 0; i < state_array->ucNumEntries; i++) { + u8 *idx; + power_state = (union pplib_power_state *)power_state_offset; +@@ -1765,6 +1762,10 @@ int sumo_dpm_init(struct radeon_device *rdev) + + sumo_construct_boot_and_acpi_state(rdev); + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = sumo_parse_power_table(rdev); + if (ret) + return ret; +diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c +index d700698..ab32576 100644 +--- a/drivers/gpu/drm/radeon/trinity_dpm.c ++++ b/drivers/gpu/drm/radeon/trinity_dpm.c +@@ -1685,9 +1685,6 @@ static int trinity_parse_power_table(struct radeon_device *rdev) + if (!rdev->pm.dpm.ps) + return -ENOMEM; + power_state_offset = (u8 *)state_array->states; +- rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps); +- rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); +- rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); + for (i = 0; i < state_array->ucNumEntries; i++) { + u8 *idx; + power_state = (union pplib_power_state *)power_state_offset; +@@ -1886,6 +1883,10 @@ int trinity_dpm_init(struct radeon_device *rdev) + + trinity_construct_boot_state(rdev); + ++ ret = r600_get_platform_caps(rdev); ++ if (ret) ++ return ret; ++ + ret = trinity_parse_power_table(rdev); + if (ret) + return ret; +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0032-yocto-amd-drm-radeon-dpm-fill-in-some-initial-vce-infrastructu.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0032-yocto-amd-drm-radeon-dpm-fill-in-some-initial-vce-infrastructu.patch new file mode 100644 index 00000000..00f558dc --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0032-yocto-amd-drm-radeon-dpm-fill-in-some-initial-vce-infrastructu.patch @@ -0,0 +1,84 @@ +From e539bcfbb6e46e51b7a463078e3bf3a7ae4c28d7 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Tue, 20 Aug 2013 20:29:05 -0400 +Subject: [PATCH 32/44] drm/radeon/dpm: fill in some initial vce + infrastructure + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 12 ++++++++++++ + drivers/gpu/drm/radeon/radeon_pm.c | 7 +++++++ + 2 files changed, 19 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index f0ad724..7846289 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -1253,6 +1253,15 @@ enum radeon_dpm_event_src { + RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4 + }; + ++enum radeon_vce_level { ++ RADEON_VCE_LEVEL_AC_ALL = 0, /* AC, All cases */ ++ RADEON_VCE_LEVEL_DC_EE = 1, /* DC, entropy encoding */ ++ RADEON_VCE_LEVEL_DC_LL_LOW = 2, /* DC, low latency queue, res <= 720 */ ++ RADEON_VCE_LEVEL_DC_LL_HIGH = 3, /* DC, low latency queue, 1080 >= res > 720 */ ++ RADEON_VCE_LEVEL_DC_GP_LOW = 4, /* DC, general purpose queue, res <= 720 */ ++ RADEON_VCE_LEVEL_DC_GP_HIGH = 5, /* DC, general purpose queue, 1080 >= res > 720 */ ++}; ++ + struct radeon_ps { + u32 caps; /* vbios flags */ + u32 class; /* vbios flags */ +@@ -1263,6 +1272,8 @@ struct radeon_ps { + /* VCE clocks */ + u32 evclk; + u32 ecclk; ++ bool vce_active; ++ enum radeon_vce_level vce_level; + /* asic priv */ + void *ps_priv; + }; +@@ -1474,6 +1485,7 @@ struct radeon_dpm { + /* special states active */ + bool thermal_active; + bool uvd_active; ++ bool vce_active; + /* thermal handling */ + struct radeon_dpm_thermal thermal; + /* forced levels */ +diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c +index 5febb25..366bf38 100644 +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -845,6 +845,9 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) + + /* no need to reprogram if nothing changed unless we are on BTC+ */ + if (rdev->pm.dpm.current_ps == rdev->pm.dpm.requested_ps) { ++ /* vce just modifies an existing state so force a change */ ++ if (ps->vce_active != rdev->pm.dpm.vce_active) ++ goto force; + if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) { + /* for pre-BTC and APUs if the num crtcs changed but state is the same, + * all we need to do is update the display configuration. +@@ -881,6 +884,7 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) + } + } + ++force: + printk("switching from power state:\n"); + radeon_dpm_print_power_state(rdev, rdev->pm.dpm.current_ps); + printk("switching to power state:\n"); +@@ -890,6 +894,9 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) + down_write(&rdev->pm.mclk_lock); + mutex_lock(&rdev->ring_lock); + ++ /* update whether vce is active */ ++ ps->vce_active = rdev->pm.dpm.vce_active; ++ + ret = radeon_dpm_pre_set_power_state(rdev); + if (ret) + goto done; +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0033-yocto-amd-drm-radeon-dpm-fetch-vce-states-from-the-vbios.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0033-yocto-amd-drm-radeon-dpm-fetch-vce-states-from-the-vbios.patch new file mode 100644 index 00000000..aa4de719 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0033-yocto-amd-drm-radeon-dpm-fetch-vce-states-from-the-vbios.patch @@ -0,0 +1,110 @@ +From 55d04c82da7399c568896c2938a8729989e43c8d Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Wed, 4 Sep 2013 16:13:56 -0400 +Subject: [PATCH 33/44] drm/radeon/dpm: fetch vce states from the vbios + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/r600_dpm.c | 28 +++++++++++++++++++++++++++- + drivers/gpu/drm/radeon/radeon.h | 16 ++++++++++++++++ + 2 files changed, 43 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c +index d57cde7..0bad36b 100644 +--- a/drivers/gpu/drm/radeon/r600_dpm.c ++++ b/drivers/gpu/drm/radeon/r600_dpm.c +@@ -1047,7 +1047,15 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) + (mode_info->atom_context->bios + data_offset + + le16_to_cpu(ext_hdr->usVCETableOffset) + 1 + + 1 + array->ucNumEntries * sizeof(VCEClockInfo)); ++ ATOM_PPLIB_VCE_State_Table *states = ++ (ATOM_PPLIB_VCE_State_Table *) ++ (mode_info->atom_context->bios + data_offset + ++ le16_to_cpu(ext_hdr->usVCETableOffset) + 1 + ++ 1 + (array->ucNumEntries * sizeof (VCEClockInfo)) + ++ 1 + (limits->numEntries * sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record))); + ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry; ++ ATOM_PPLIB_VCE_State_Record *state_entry; ++ VCEClockInfo *vce_clk; + u32 size = limits->numEntries * + sizeof(struct radeon_vce_clock_voltage_dependency_entry); + rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries = +@@ -1059,8 +1067,9 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) + rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count = + limits->numEntries; + entry = &limits->entries[0]; ++ state_entry = &states->entries[0]; + for (i = 0; i < limits->numEntries; i++) { +- VCEClockInfo *vce_clk = (VCEClockInfo *) ++ vce_clk = (VCEClockInfo *) + ((u8 *)&array->entries[0] + + (entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo))); + rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk = +@@ -1072,6 +1081,23 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) + entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *) + ((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)); + } ++ for (i = 0; i < states->numEntries; i++) { ++ if (i >= RADEON_MAX_VCE_LEVELS) ++ break; ++ vce_clk = (VCEClockInfo *) ++ ((u8 *)&array->entries[0] + ++ (state_entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo))); ++ rdev->pm.dpm.vce_states[i].evclk = ++ le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16); ++ rdev->pm.dpm.vce_states[i].ecclk = ++ le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16); ++ rdev->pm.dpm.vce_states[i].clk_idx = ++ state_entry->ucClockInfoIndex & 0x3f; ++ rdev->pm.dpm.vce_states[i].pstate = ++ (state_entry->ucClockInfoIndex & 0xc0) >> 6; ++ state_entry = (ATOM_PPLIB_VCE_State_Record *) ++ ((u8 *)state_entry + sizeof(ATOM_PPLIB_VCE_State_Record)); ++ } + } + if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) && + ext_hdr->usUVDTableOffset) { +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 7846289..fa57b11 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -1253,6 +1253,8 @@ enum radeon_dpm_event_src { + RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4 + }; + ++#define RADEON_MAX_VCE_LEVELS 6 ++ + enum radeon_vce_level { + RADEON_VCE_LEVEL_AC_ALL = 0, /* AC, All cases */ + RADEON_VCE_LEVEL_DC_EE = 1, /* DC, entropy encoding */ +@@ -1448,6 +1450,17 @@ enum radeon_dpm_forced_level { + RADEON_DPM_FORCED_LEVEL_HIGH = 2, + }; + ++struct radeon_vce_state { ++ /* vce clocks */ ++ u32 evclk; ++ u32 ecclk; ++ /* gpu clocks */ ++ u32 sclk; ++ u32 mclk; ++ u8 clk_idx; ++ u8 pstate; ++}; ++ + struct radeon_dpm { + struct radeon_ps *ps; + /* number of valid power states */ +@@ -1460,6 +1473,9 @@ struct radeon_dpm { + struct radeon_ps *boot_ps; + /* default uvd power state */ + struct radeon_ps *uvd_ps; ++ /* vce requirements */ ++ struct radeon_vce_state vce_states[RADEON_MAX_VCE_LEVELS]; ++ enum radeon_vce_level vce_level; + enum radeon_pm_state_type state; + enum radeon_pm_state_type user_state; + u32 platform_caps; +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0034-yocto-amd-drm-radeon-fill-in-set_vce_clocks-for-CIK-asics.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0034-yocto-amd-drm-radeon-fill-in-set_vce_clocks-for-CIK-asics.patch new file mode 100644 index 00000000..d4669a9f --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0034-yocto-amd-drm-radeon-fill-in-set_vce_clocks-for-CIK-asics.patch @@ -0,0 +1,111 @@ +From bfe1cb3c1990b0e7a80ffe5563c86d52292b1565 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Thu, 22 Aug 2013 17:09:06 -0400 +Subject: [PATCH 34/44] drm/radeon: fill in set_vce_clocks for CIK asics + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/cik.c | 35 ++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/radeon/cikd.h | 6 ++++++ + drivers/gpu/drm/radeon/radeon_asic.c | 2 ++ + drivers/gpu/drm/radeon/radeon_asic.h | 1 + + 4 files changed, 44 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index 872b146..9af1f3f 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -8115,6 +8115,41 @@ int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) + return r; + } + ++int cik_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk) ++{ ++ int r, i; ++ struct atom_clock_dividers dividers; ++ u32 tmp; ++ ++ r = radeon_atom_get_clock_dividers(rdev, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, ++ ecclk, false, ÷rs); ++ if (r) ++ return r; ++ ++ for (i = 0; i < 100; i++) { ++ if (RREG32_SMC(CG_ECLK_STATUS) & ECLK_STATUS) ++ break; ++ mdelay(10); ++ } ++ if (i == 100) ++ return -ETIMEDOUT; ++ ++ tmp = RREG32_SMC(CG_ECLK_CNTL); ++ tmp &= ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK); ++ tmp |= dividers.post_divider; ++ WREG32_SMC(CG_ECLK_CNTL, tmp); ++ ++ for (i = 0; i < 100; i++) { ++ if (RREG32_SMC(CG_ECLK_STATUS) & ECLK_STATUS) ++ break; ++ mdelay(10); ++ } ++ if (i == 100) ++ return -ETIMEDOUT; ++ ++ return 0; ++} ++ + static void cik_pcie_gen3_enable(struct radeon_device *rdev) + { + struct pci_dev *root = rdev->pdev->bus->self; +diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h +index b296d50..3224176 100644 +--- a/drivers/gpu/drm/radeon/cikd.h ++++ b/drivers/gpu/drm/radeon/cikd.h +@@ -201,6 +201,12 @@ + #define CTF_TEMP_MASK 0x0003fe00 + #define CTF_TEMP_SHIFT 9 + ++#define CG_ECLK_CNTL 0xC05000AC ++# define ECLK_DIVIDER_MASK 0x7f ++# define ECLK_DIR_CNTL_EN (1 << 8) ++#define CG_ECLK_STATUS 0xC05000B0 ++# define ECLK_STATUS (1 << 0) ++ + #define CG_SPLL_FUNC_CNTL 0xC0500140 + #define SPLL_RESET (1 << 0) + #define SPLL_PWRON (1 << 1) +diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c +index 763280b..19b2eea 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.c ++++ b/drivers/gpu/drm/radeon/radeon_asic.c +@@ -2067,6 +2067,7 @@ static struct radeon_asic ci_asic = { + .set_pcie_lanes = NULL, + .set_clock_gating = NULL, + .set_uvd_clocks = &cik_set_uvd_clocks, ++ .set_vce_clocks = &cik_set_vce_clocks, + .get_temperature = &ci_get_temp, + }, + .dpm = { +@@ -2170,6 +2171,7 @@ static struct radeon_asic kv_asic = { + .set_pcie_lanes = NULL, + .set_clock_gating = NULL, + .set_uvd_clocks = &cik_set_uvd_clocks, ++ .set_vce_clocks = &cik_set_vce_clocks, + .get_temperature = &kv_get_temp, + }, + .dpm = { +diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h +index a6c3eeb..900ffd7 100644 +--- a/drivers/gpu/drm/radeon/radeon_asic.h ++++ b/drivers/gpu/drm/radeon/radeon_asic.h +@@ -710,6 +710,7 @@ u32 cik_get_xclk(struct radeon_device *rdev); + uint32_t cik_pciep_rreg(struct radeon_device *rdev, uint32_t reg); + void cik_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); + int cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); ++int cik_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk); + void cik_sdma_fence_ring_emit(struct radeon_device *rdev, + struct radeon_fence *fence); + bool cik_sdma_semaphore_ring_emit(struct radeon_device *rdev, +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0035-yocto-amd-drm-radeon-add-vce-dpm-support-for-CI.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0035-yocto-amd-drm-radeon-add-vce-dpm-support-for-CI.patch new file mode 100644 index 00000000..1ec9eb39 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0035-yocto-amd-drm-radeon-add-vce-dpm-support-for-CI.patch @@ -0,0 +1,149 @@ +From 82cd2bfeb87f0d4e65537765399014748e8aa80f Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Fri, 23 Aug 2013 11:05:24 -0400 +Subject: [PATCH 35/44] drm/radeon: add vce dpm support for CI + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/ci_dpm.c | 50 +++++++++++++++++++++++++++++++-------- + 1 file changed, 40 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c +index b90834a..69f34f8 100644 +--- a/drivers/gpu/drm/radeon/ci_dpm.c ++++ b/drivers/gpu/drm/radeon/ci_dpm.c +@@ -717,6 +717,14 @@ static void ci_apply_state_adjust_rules(struct radeon_device *rdev, + u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; + int i; + ++ if (rps->vce_active) { ++ rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk; ++ rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk; ++ } else { ++ rps->evclk = 0; ++ rps->ecclk = 0; ++ } ++ + if ((rdev->pm.dpm.new_active_crtc_count > 1) || + ci_dpm_vblank_too_short(rdev)) + disable_mclk_switching = true; +@@ -775,6 +783,13 @@ static void ci_apply_state_adjust_rules(struct radeon_device *rdev, + sclk = ps->performance_levels[0].sclk; + } + ++ if (rps->vce_active) { ++ if (sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk) ++ sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk; ++ if (mclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].mclk) ++ mclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].mclk; ++ } ++ + ps->performance_levels[0].sclk = sclk; + ps->performance_levels[0].mclk = mclk; + +@@ -3439,7 +3454,6 @@ static int ci_enable_uvd_dpm(struct radeon_device *rdev, bool enable) + 0 : -EINVAL; + } + +-#if 0 + static int ci_enable_vce_dpm(struct radeon_device *rdev, bool enable) + { + struct ci_power_info *pi = ci_get_pi(rdev); +@@ -3472,6 +3486,7 @@ static int ci_enable_vce_dpm(struct radeon_device *rdev, bool enable) + 0 : -EINVAL; + } + ++#if 0 + static int ci_enable_samu_dpm(struct radeon_device *rdev, bool enable) + { + struct ci_power_info *pi = ci_get_pi(rdev); +@@ -3558,7 +3573,6 @@ static int ci_update_uvd_dpm(struct radeon_device *rdev, bool gate) + return ci_enable_uvd_dpm(rdev, !gate); + } + +-#if 0 + static u8 ci_get_vce_boot_level(struct radeon_device *rdev) + { + u8 i; +@@ -3579,13 +3593,11 @@ static int ci_update_vce_dpm(struct radeon_device *rdev, + struct radeon_ps *radeon_current_state) + { + struct ci_power_info *pi = ci_get_pi(rdev); +- bool new_vce_clock_non_zero = (radeon_new_state->evclk != 0); +- bool old_vce_clock_non_zero = (radeon_current_state->evclk != 0); + int ret = 0; + u32 tmp; + +- if (new_vce_clock_non_zero != old_vce_clock_non_zero) { +- if (new_vce_clock_non_zero) { ++ if (radeon_current_state->evclk != radeon_new_state->evclk) { ++ if (radeon_new_state->evclk) { + pi->smc_state_table.VceBootLevel = ci_get_vce_boot_level(rdev); + + tmp = RREG32_SMC(DPM_TABLE_475); +@@ -3601,6 +3613,7 @@ static int ci_update_vce_dpm(struct radeon_device *rdev, + return ret; + } + ++#if 0 + static int ci_update_samu_dpm(struct radeon_device *rdev, bool gate) + { + return ci_enable_samu_dpm(rdev, gate); +@@ -4737,13 +4750,13 @@ int ci_dpm_set_power_state(struct radeon_device *rdev) + DRM_ERROR("ci_generate_dpm_level_enable_mask failed\n"); + return ret; + } +-#if 0 ++ + ret = ci_update_vce_dpm(rdev, new_ps, old_ps); + if (ret) { + DRM_ERROR("ci_update_vce_dpm failed\n"); + return ret; + } +-#endif ++ + ret = ci_update_sclk_t(rdev); + if (ret) { + DRM_ERROR("ci_update_sclk_t failed\n"); +@@ -4987,6 +5000,21 @@ static int ci_parse_power_table(struct radeon_device *rdev) + power_state_offset += 2 + power_state->v2.ucNumDPMLevels; + } + rdev->pm.dpm.num_ps = state_array->ucNumEntries; ++ ++ /* fill in the vce power states */ ++ for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) { ++ u32 sclk, mclk; ++ clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx; ++ clock_info = (union pplib_clock_info *) ++ &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; ++ sclk = le16_to_cpu(clock_info->ci.usEngineClockLow); ++ sclk |= clock_info->ci.ucEngineClockHigh << 16; ++ mclk = le16_to_cpu(clock_info->ci.usMemoryClockLow); ++ mclk |= clock_info->ci.ucMemoryClockHigh << 16; ++ rdev->pm.dpm.vce_states[i].sclk = sclk; ++ rdev->pm.dpm.vce_states[i].mclk = mclk; ++ } ++ + return 0; + } + +@@ -5072,12 +5100,14 @@ int ci_dpm_init(struct radeon_device *rdev) + ci_dpm_fini(rdev); + return ret; + } +- ret = ci_parse_power_table(rdev); ++ ++ ret = r600_parse_extended_power_table(rdev); + if (ret) { + ci_dpm_fini(rdev); + return ret; + } +- ret = r600_parse_extended_power_table(rdev); ++ ++ ret = ci_parse_power_table(rdev); + if (ret) { + ci_dpm_fini(rdev); + return ret; +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0036-yocto-amd-drm-radeon-enable-vce-dpm-on-CI.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0036-yocto-amd-drm-radeon-enable-vce-dpm-on-CI.patch new file mode 100644 index 00000000..2e115f87 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0036-yocto-amd-drm-radeon-enable-vce-dpm-on-CI.patch @@ -0,0 +1,28 @@ +From dceb1d2ab717808241bf302878eb7e351d65a680 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Fri, 23 Aug 2013 11:09:21 -0400 +Subject: [PATCH 36/44] drm/radeon: enable vce dpm on CI + +VCE dpm dynamically adjusts the uvd clocks on +demand. + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/ci_dpm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c +index 69f34f8..a6a2396 100644 +--- a/drivers/gpu/drm/radeon/ci_dpm.c ++++ b/drivers/gpu/drm/radeon/ci_dpm.c +@@ -5145,6 +5145,7 @@ int ci_dpm_init(struct radeon_device *rdev) + pi->caps_sclk_throttle_low_notification = false; + + pi->caps_uvd_dpm = true; ++ pi->caps_vce_dpm = true; + + ci_get_leakage_voltages(rdev); + ci_patch_dependency_tables_with_leakage(rdev); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0037-yocto-amd-drm-radeon-add-vce-dpm-support-for-KV-KB.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0037-yocto-amd-drm-radeon-add-vce-dpm-support-for-KV-KB.patch new file mode 100644 index 00000000..d8243434 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0037-yocto-amd-drm-radeon-add-vce-dpm-support-for-KV-KB.patch @@ -0,0 +1,169 @@ +From 397c2ed05a91152697a262867db2b68ec997dbef Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Wed, 4 Sep 2013 16:17:07 -0400 +Subject: [PATCH 37/44] drm/radeon: add vce dpm support for KV/KB + +TODO: plug in cik_vce_suspend()/resume() so we can enable +vce powergating. See XXX in code. + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/kv_dpm.c | 46 +++++++++++++++++++++++++++++---------- + 1 file changed, 35 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c +index 58b5a5d..feacd5c 100644 +--- a/drivers/gpu/drm/radeon/kv_dpm.c ++++ b/drivers/gpu/drm/radeon/kv_dpm.c +@@ -1346,13 +1346,11 @@ static int kv_enable_uvd_dpm(struct radeon_device *rdev, bool enable) + PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable); + } + +-#if 0 + static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable) + { + return kv_notify_message_to_smu(rdev, enable ? + PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable); + } +-#endif + + static int kv_enable_samu_dpm(struct radeon_device *rdev, bool enable) + { +@@ -1397,7 +1395,6 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate) + return kv_enable_uvd_dpm(rdev, !gate); + } + +-#if 0 + static u8 kv_get_vce_boot_level(struct radeon_device *rdev) + { + u8 i; +@@ -1422,6 +1419,8 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, + int ret; + + if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) { ++ kv_dpm_powergate_vce(rdev, false); ++ /* XXX cik_vce_resume(); */ + if (pi->caps_stable_p_state) + pi->vce_boot_level = table->count - 1; + else +@@ -1444,11 +1443,12 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, + kv_enable_vce_dpm(rdev, true); + } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) { + kv_enable_vce_dpm(rdev, false); ++ /* XXX cik_vce_suspend(); */ ++ kv_dpm_powergate_vce(rdev, true); + } + + return 0; + } +-#endif + + static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate) + { +@@ -1776,7 +1776,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) + { + struct kv_power_info *pi = kv_get_pi(rdev); + struct radeon_ps *new_ps = &pi->requested_rps; +- /*struct radeon_ps *old_ps = &pi->current_rps;*/ ++ struct radeon_ps *old_ps = &pi->current_rps; + int ret; + + cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | +@@ -1811,13 +1811,12 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) + kv_set_enabled_levels(rdev); + kv_force_lowest_valid(rdev); + kv_unforce_levels(rdev); +-#if 0 ++ + ret = kv_update_vce_dpm(rdev, new_ps, old_ps); + if (ret) { + DRM_ERROR("kv_update_vce_dpm failed\n"); + return ret; + } +-#endif + kv_update_sclk_t(rdev); + } + } else { +@@ -1836,13 +1835,11 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) + kv_program_nbps_index_settings(rdev, new_ps); + kv_freeze_sclk_dpm(rdev, false); + kv_set_enabled_levels(rdev); +-#if 0 + ret = kv_update_vce_dpm(rdev, new_ps, old_ps); + if (ret) { + DRM_ERROR("kv_update_vce_dpm failed\n"); + return ret; + } +-#endif + kv_update_acp_boot_level(rdev); + kv_update_sclk_t(rdev); + kv_enable_nb_dpm(rdev); +@@ -2055,6 +2052,14 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, + struct radeon_clock_and_voltage_limits *max_limits = + &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; + ++ if (new_rps->vce_active) { ++ new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk; ++ new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk; ++ } else { ++ new_rps->evclk = 0; ++ new_rps->ecclk = 0; ++ } ++ + mclk = max_limits->mclk; + sclk = min_sclk; + +@@ -2074,6 +2079,11 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, + sclk = stable_p_state_sclk; + } + ++ if (new_rps->vce_active) { ++ if (sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk) ++ sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk; ++ } ++ + ps->need_dfs_bypass = true; + + for (i = 0; i < ps->num_levels; i++) { +@@ -2110,7 +2120,8 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, + } + } + +- pi->video_start = new_rps->dclk || new_rps->vclk; ++ pi->video_start = new_rps->dclk || new_rps->vclk || ++ new_rps->evclk || new_rps->ecclk; + + if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == + ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) +@@ -2592,6 +2603,19 @@ static int kv_parse_power_table(struct radeon_device *rdev) + power_state_offset += 2 + power_state->v2.ucNumDPMLevels; + } + rdev->pm.dpm.num_ps = state_array->ucNumEntries; ++ ++ /* fill in the vce power states */ ++ for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) { ++ u32 sclk; ++ clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx; ++ clock_info = (union pplib_clock_info *) ++ &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; ++ sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); ++ sclk |= clock_info->sumo.ucEngineClockHigh << 16; ++ rdev->pm.dpm.vce_states[i].sclk = sclk; ++ rdev->pm.dpm.vce_states[i].mclk = 0; ++ } ++ + return 0; + } + +@@ -2642,7 +2666,7 @@ int kv_dpm_init(struct radeon_device *rdev) + pi->caps_fps = false; /* true? */ + pi->caps_uvd_pg = true; + pi->caps_uvd_dpm = true; +- pi->caps_vce_pg = false; ++ pi->caps_vce_pg = false; /* XXX true */ + pi->caps_samu_pg = false; + pi->caps_acp_pg = false; + pi->caps_stable_p_state = false; +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0038-yocto-amd-drm-radeon-dpm-enable-dynamic-vce-state-switching-v2.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0038-yocto-amd-drm-radeon-dpm-enable-dynamic-vce-state-switching-v2.patch new file mode 100644 index 00000000..f06637bf --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0038-yocto-amd-drm-radeon-dpm-enable-dynamic-vce-state-switching-v2.patch @@ -0,0 +1,195 @@ +From 4d64b74b580760a85dc3349877a2bef2fbf779da Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Fri, 23 Aug 2013 11:56:26 -0400 +Subject: [PATCH 38/44] drm/radeon/dpm: enable dynamic vce state switching v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +enable vce states when vce is active. When vce is active, +it adjusts the currently selected state (performance, battery, +uvd, etc.) + +v2: add code comments + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 3 ++ + drivers/gpu/drm/radeon/radeon_cs.c | 3 ++ + drivers/gpu/drm/radeon/radeon_pm.c | 17 ++++++++++ + drivers/gpu/drm/radeon/radeon_vce.c | 62 +++++++++++++++++++++++++++++++++++ + 4 files changed, 85 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index fa57b11..74928d5 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -1512,6 +1512,7 @@ struct radeon_dpm { + }; + + void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable); ++void radeon_dpm_enable_vce(struct radeon_device *rdev, bool enable); + + struct radeon_pm { + struct mutex mutex; +@@ -1633,6 +1634,7 @@ struct radeon_vce { + unsigned fb_version; + atomic_t handles[RADEON_MAX_VCE_HANDLES]; + struct drm_file *filp[RADEON_MAX_VCE_HANDLES]; ++ struct delayed_work idle_work; + }; + + int radeon_vce_init(struct radeon_device *rdev); +@@ -1644,6 +1646,7 @@ int radeon_vce_get_create_msg(struct radeon_device *rdev, int ring, + int radeon_vce_get_destroy_msg(struct radeon_device *rdev, int ring, + uint32_t handle, struct radeon_fence **fence); + void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp); ++void radeon_vce_note_usage(struct radeon_device *rdev); + int radeon_vce_cs_reloc(struct radeon_cs_parser *p, int lo, int hi); + int radeon_vce_cs_parse(struct radeon_cs_parser *p); + bool radeon_vce_semaphore_emit(struct radeon_device *rdev, +diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c +index 2f8e92b..a55e17a 100644 +--- a/drivers/gpu/drm/radeon/radeon_cs.c ++++ b/drivers/gpu/drm/radeon/radeon_cs.c +@@ -394,6 +394,9 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, + + if (parser->ring == R600_RING_TYPE_UVD_INDEX) + radeon_uvd_note_usage(rdev); ++ else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) || ++ (parser->ring == TN_RING_TYPE_VCE2_INDEX)) ++ radeon_vce_note_usage(rdev); + + radeon_cs_sync_rings(parser); + r = radeon_ib_schedule(rdev, &parser->ib, NULL); +diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c +index 366bf38..07a7fb0 100644 +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -985,6 +985,23 @@ void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable) + } + } + ++void radeon_dpm_enable_vce(struct radeon_device *rdev, bool enable) ++{ ++ if (enable) { ++ mutex_lock(&rdev->pm.mutex); ++ rdev->pm.dpm.vce_active = true; ++ /* XXX select vce level based on ring/task */ ++ rdev->pm.dpm.vce_level = RADEON_VCE_LEVEL_AC_ALL; ++ mutex_unlock(&rdev->pm.mutex); ++ } else { ++ mutex_lock(&rdev->pm.mutex); ++ rdev->pm.dpm.vce_active = false; ++ mutex_unlock(&rdev->pm.mutex); ++ } ++ ++ radeon_pm_compute_clocks(rdev); ++} ++ + static void radeon_pm_suspend_old(struct radeon_device *rdev) + { + mutex_lock(&rdev->pm.mutex); +diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c +index f46563b..d130432 100644 +--- a/drivers/gpu/drm/radeon/radeon_vce.c ++++ b/drivers/gpu/drm/radeon/radeon_vce.c +@@ -34,11 +34,16 @@ + #include "radeon_asic.h" + #include "sid.h" + ++/* 1 second timeout */ ++#define VCE_IDLE_TIMEOUT_MS 1000 ++ + /* Firmware Names */ + #define FIRMWARE_BONAIRE "radeon/BONAIRE_vce.bin" + + MODULE_FIRMWARE(FIRMWARE_BONAIRE); + ++static void radeon_vce_idle_work_handler(struct work_struct *work); ++ + /** + * radeon_vce_init - allocate memory, load vce firmware + * +@@ -55,6 +60,8 @@ int radeon_vce_init(struct radeon_device *rdev) + uint8_t start, mid, end; + int i, r; + ++ INIT_DELAYED_WORK(&rdev->vce.idle_work, radeon_vce_idle_work_handler); ++ + switch (rdev->family) { + case CHIP_BONAIRE: + case CHIP_KAVERI: +@@ -220,6 +227,59 @@ int radeon_vce_resume(struct radeon_device *rdev) + } + + /** ++ * radeon_vce_idle_work_handler - power off VCE ++ * ++ * @work: pointer to work structure ++ * ++ * power of VCE when it's not used any more ++ */ ++static void radeon_vce_idle_work_handler(struct work_struct *work) ++{ ++ struct radeon_device *rdev = ++ container_of(work, struct radeon_device, vce.idle_work.work); ++ ++ if ((radeon_fence_count_emitted(rdev, TN_RING_TYPE_VCE1_INDEX) == 0) && ++ (radeon_fence_count_emitted(rdev, TN_RING_TYPE_VCE2_INDEX) == 0)) { ++ if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { ++ radeon_dpm_enable_vce(rdev, false); ++ } else { ++ radeon_set_vce_clocks(rdev, 0, 0); ++ } ++ } else { ++ schedule_delayed_work(&rdev->vce.idle_work, ++ msecs_to_jiffies(VCE_IDLE_TIMEOUT_MS)); ++ } ++} ++ ++/** ++ * radeon_vce_note_usage - power up VCE ++ * ++ * @rdev: radeon_device pointer ++ * ++ * Make sure VCE is powerd up when we want to use it ++ */ ++void radeon_vce_note_usage(struct radeon_device *rdev) ++{ ++ bool streams_changed = false; ++ bool set_clocks = !cancel_delayed_work_sync(&rdev->vce.idle_work); ++ set_clocks &= schedule_delayed_work(&rdev->vce.idle_work, ++ msecs_to_jiffies(VCE_IDLE_TIMEOUT_MS)); ++ ++ if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { ++ /* XXX figure out if the streams changed */ ++ streams_changed = false; ++ } ++ ++ if (set_clocks || streams_changed) { ++ if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { ++ radeon_dpm_enable_vce(rdev, true); ++ } else { ++ radeon_set_vce_clocks(rdev, 53300, 40000); ++ } ++ } ++} ++ ++/** + * radeon_vce_free_handles - free still open VCE handles + * + * @rdev: radeon_device pointer +@@ -235,6 +295,8 @@ void radeon_vce_free_handles(struct radeon_device *rdev, struct drm_file *filp) + if (!handle || rdev->vce.filp[i] != filp) + continue; + ++ radeon_vce_note_usage(rdev); ++ + r = radeon_vce_get_destroy_msg(rdev, TN_RING_TYPE_VCE1_INDEX, + handle, NULL); + if (r) +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0039-yocto-amd-drm-radeon-dpm-properly-enable-disable-vce-when-vce-.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0039-yocto-amd-drm-radeon-dpm-properly-enable-disable-vce-when-vce-.patch new file mode 100644 index 00000000..4004dba2 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0039-yocto-amd-drm-radeon-dpm-properly-enable-disable-vce-when-vce-.patch @@ -0,0 +1,56 @@ +From 3320b5c1ae158d1e41bbe05b15495d4b2bce972b Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Wed, 28 Aug 2013 18:53:50 -0400 +Subject: [PATCH 39/44] drm/radeon/dpm: properly enable/disable vce when vce + pg is enabled + +The adds the appropriate function calls to properly re-init +vce before it's used after it has been power gated. + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/kv_dpm.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c +index feacd5c..c8b9d7b 100644 +--- a/drivers/gpu/drm/radeon/kv_dpm.c ++++ b/drivers/gpu/drm/radeon/kv_dpm.c +@@ -1420,7 +1420,6 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, + + if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) { + kv_dpm_powergate_vce(rdev, false); +- /* XXX cik_vce_resume(); */ + if (pi->caps_stable_p_state) + pi->vce_boot_level = table->count - 1; + else +@@ -1443,7 +1442,6 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, + kv_enable_vce_dpm(rdev, true); + } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) { + kv_enable_vce_dpm(rdev, false); +- /* XXX cik_vce_suspend(); */ + kv_dpm_powergate_vce(rdev, true); + } + +@@ -1583,11 +1581,16 @@ static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate) + pi->vce_power_gated = gate; + + if (gate) { +- if (pi->caps_vce_pg) ++ if (pi->caps_vce_pg) { ++ /* XXX do we need a vce_v1_0_stop() ? */ + kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerOFF); ++ } + } else { +- if (pi->caps_vce_pg) ++ if (pi->caps_vce_pg) { + kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerON); ++ vce_v2_0_resume(rdev); ++ vce_v1_0_start(rdev); ++ } + } + } + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0040-yocto-amd-drm-radeon-add-vce-debugfs-support.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0040-yocto-amd-drm-radeon-add-vce-debugfs-support.patch new file mode 100644 index 00000000..9e322246 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0040-yocto-amd-drm-radeon-add-vce-debugfs-support.patch @@ -0,0 +1,98 @@ +From da27d56b608ad65f5d76924afd66b82d64e069cb Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Mon, 25 Nov 2013 17:30:38 -0500 +Subject: [PATCH 40/44] drm/radeon: add vce debugfs support + +Signed-off-by: Leo Liu <leo.liu@amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 1 + + drivers/gpu/drm/radeon/radeon_vce.c | 37 +++++++++++++++++++++++++++++++++++ + 2 files changed, 38 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index 74928d5..f3a4f34 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -1635,6 +1635,7 @@ struct radeon_vce { + atomic_t handles[RADEON_MAX_VCE_HANDLES]; + struct drm_file *filp[RADEON_MAX_VCE_HANDLES]; + struct delayed_work idle_work; ++ bool status; + }; + + int radeon_vce_init(struct radeon_device *rdev); +diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c +index d130432..eb11ac0 100644 +--- a/drivers/gpu/drm/radeon/radeon_vce.c ++++ b/drivers/gpu/drm/radeon/radeon_vce.c +@@ -41,6 +41,7 @@ + #define FIRMWARE_BONAIRE "radeon/BONAIRE_vce.bin" + + MODULE_FIRMWARE(FIRMWARE_BONAIRE); ++static int radeon_debugfs_vce_init(struct radeon_device *rdev); + + static void radeon_vce_idle_work_handler(struct work_struct *work); + +@@ -146,6 +147,10 @@ int radeon_vce_init(struct radeon_device *rdev) + rdev->vce.filp[i] = NULL; + } + ++ r = radeon_debugfs_vce_init(rdev); ++ if (r) ++ dev_err(rdev->dev, "(%d) Register debugfs file for vce failed\n", r); ++ + return 0; + } + +@@ -249,6 +254,7 @@ static void radeon_vce_idle_work_handler(struct work_struct *work) + schedule_delayed_work(&rdev->vce.idle_work, + msecs_to_jiffies(VCE_IDLE_TIMEOUT_MS)); + } ++ rdev->vce.status = false; + } + + /** +@@ -276,9 +282,40 @@ void radeon_vce_note_usage(struct radeon_device *rdev) + } else { + radeon_set_vce_clocks(rdev, 53300, 40000); + } ++ rdev->vce.status = true; + } + } + ++/* ++ * Debugfs info ++ */ ++#if defined(CONFIG_DEBUG_FS) ++ ++static int radeon_debugfs_vce_info(struct seq_file *m, void *data) ++{ ++ struct drm_info_node *node = (struct drm_info_node *) m->private; ++ struct drm_device *dev = node->minor->dev; ++ struct radeon_device *rdev = dev->dev_private; ++ ++ seq_printf(m, "VCE Status: %s\n", ((rdev->vce.status) ? "Busy" : "Idle")); ++ ++ return 0; ++} ++ ++static struct drm_info_list radeon_vce_info_list[] = { ++ {"radeon_vce_info", radeon_debugfs_vce_info, 0, NULL}, ++}; ++#endif ++ ++static int radeon_debugfs_vce_init(struct radeon_device *rdev) ++{ ++#if defined(CONFIG_DEBUG_FS) ++ return radeon_debugfs_add_files(rdev, radeon_vce_info_list, ARRAY_SIZE(radeon_vce_info_list)); ++#else ++ return 0; ++#endif ++} ++ + /** + * radeon_vce_free_handles - free still open VCE handles + * +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0041-yocto-amd-drm-radeon-add-support-for-vce-2.0-clock-gating.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0041-yocto-amd-drm-radeon-add-support-for-vce-2.0-clock-gating.patch new file mode 100644 index 00000000..21d14e67 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0041-yocto-amd-drm-radeon-add-support-for-vce-2.0-clock-gating.patch @@ -0,0 +1,165 @@ +From 9b70ef3255b81076ded9f0388e3c2ca3519a3239 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Thu, 5 Sep 2013 15:14:28 -0400 +Subject: [PATCH 41/44] drm/radeon: add support for vce 2.0 clock gating + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/cikd.h | 10 ++++ + drivers/gpu/drm/radeon/vce_v2_0.c | 111 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 121 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h +index 3224176..f6e7ea0 100644 +--- a/drivers/gpu/drm/radeon/cikd.h ++++ b/drivers/gpu/drm/radeon/cikd.h +@@ -1918,8 +1918,18 @@ + #define VCE_RB_RPTR 0x2018c + #define VCE_RB_WPTR 0x20190 + #define VCE_CLOCK_GATING_A 0x202f8 ++# define CGC_CLK_GATE_DLY_TIMER_MASK (0xf << 0) ++# define CGC_CLK_GATE_DLY_TIMER(x) ((x) << 0) ++# define CGC_CLK_GATER_OFF_DLY_TIMER_MASK (0xff << 4) ++# define CGC_CLK_GATER_OFF_DLY_TIMER(x) ((x) << 4) ++# define CGC_UENC_WAIT_AWAKE (1 << 18) + #define VCE_CLOCK_GATING_B 0x202fc ++#define VCE_CGTT_CLK_OVERRIDE 0x207a0 + #define VCE_UENC_CLOCK_GATING 0x207bc ++# define CLOCK_ON_DELAY_MASK (0xf << 0) ++# define CLOCK_ON_DELAY(x) ((x) << 0) ++# define CLOCK_OFF_DELAY_MASK (0xff << 4) ++# define CLOCK_OFF_DELAY(x) ((x) << 4) + #define VCE_UENC_REG_CLOCK_GATING 0x207c0 + #define VCE_SYS_INT_EN 0x21300 + # define VCE_SYS_INT_TRAP_INTERRUPT_EN (1 << 3) +diff --git a/drivers/gpu/drm/radeon/vce_v2_0.c b/drivers/gpu/drm/radeon/vce_v2_0.c +index 4911d1b..1ac7bb8 100644 +--- a/drivers/gpu/drm/radeon/vce_v2_0.c ++++ b/drivers/gpu/drm/radeon/vce_v2_0.c +@@ -31,6 +31,115 @@ + #include "radeon_asic.h" + #include "cikd.h" + ++static void vce_v2_0_set_sw_cg(struct radeon_device *rdev, bool gated) ++{ ++ u32 tmp; ++ ++ if (gated) { ++ tmp = RREG32(VCE_CLOCK_GATING_B); ++ tmp |= 0xe70000; ++ WREG32(VCE_CLOCK_GATING_B, tmp); ++ ++ tmp = RREG32(VCE_UENC_CLOCK_GATING); ++ tmp |= 0xff000000; ++ WREG32(VCE_UENC_CLOCK_GATING, tmp); ++ ++ tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); ++ tmp &= ~0x3fc; ++ WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); ++ ++ WREG32(VCE_CGTT_CLK_OVERRIDE, 0); ++ } else { ++ tmp = RREG32(VCE_CLOCK_GATING_B); ++ tmp |= 0xe7; ++ tmp &= ~0xe70000; ++ WREG32(VCE_CLOCK_GATING_B, tmp); ++ ++ tmp = RREG32(VCE_UENC_CLOCK_GATING); ++ tmp |= 0x1fe000; ++ tmp &= ~0xff000000; ++ WREG32(VCE_UENC_CLOCK_GATING, tmp); ++ ++ tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); ++ tmp |= 0x3fc; ++ WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); ++ } ++} ++ ++static void vce_v2_0_set_dyn_cg(struct radeon_device *rdev, bool gated) ++{ ++ u32 orig, tmp; ++ ++ tmp = RREG32(VCE_CLOCK_GATING_B); ++ tmp &= ~0x00060006; ++ if (gated) { ++ tmp |= 0xe10000; ++ } else { ++ tmp |= 0xe1; ++ tmp &= ~0xe10000; ++ } ++ WREG32(VCE_CLOCK_GATING_B, tmp); ++ ++ orig = tmp = RREG32(VCE_UENC_CLOCK_GATING); ++ tmp &= ~0x1fe000; ++ tmp &= ~0xff000000; ++ if (tmp != orig) ++ WREG32(VCE_UENC_CLOCK_GATING, tmp); ++ ++ orig = tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); ++ tmp &= ~0x3fc; ++ if (tmp != orig) ++ WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); ++ ++ if (gated) ++ WREG32(VCE_CGTT_CLK_OVERRIDE, 0); ++} ++ ++static void vce_v2_0_disable_cg(struct radeon_device *rdev) ++{ ++ WREG32(VCE_CGTT_CLK_OVERRIDE, 7); ++} ++ ++void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable) ++{ ++ bool sw_cg = false; ++ ++ if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) { ++ if (sw_cg) ++ vce_v2_0_set_sw_cg(rdev, true); ++ else ++ vce_v2_0_set_dyn_cg(rdev, true); ++ } else { ++ vce_v2_0_disable_cg(rdev); ++ ++ if (sw_cg) ++ vce_v2_0_set_sw_cg(rdev, false); ++ else ++ vce_v2_0_set_dyn_cg(rdev, false); ++ } ++} ++ ++static void vce_v2_0_init_cg(struct radeon_device *rdev) ++{ ++ u32 tmp; ++ ++ tmp = RREG32(VCE_CLOCK_GATING_A); ++ tmp &= ~(CGC_CLK_GATE_DLY_TIMER_MASK | CGC_CLK_GATER_OFF_DLY_TIMER_MASK); ++ tmp |= (CGC_CLK_GATE_DLY_TIMER(0) | CGC_CLK_GATER_OFF_DLY_TIMER(4)); ++ tmp |= CGC_UENC_WAIT_AWAKE; ++ WREG32(VCE_CLOCK_GATING_A, tmp); ++ ++ tmp = RREG32(VCE_UENC_CLOCK_GATING); ++ tmp &= ~(CLOCK_ON_DELAY_MASK | CLOCK_OFF_DELAY_MASK); ++ tmp |= (CLOCK_ON_DELAY(0) | CLOCK_OFF_DELAY(4)); ++ WREG32(VCE_UENC_CLOCK_GATING, tmp); ++ ++ tmp = RREG32(VCE_CLOCK_GATING_B); ++ tmp |= 0x10; ++ tmp &= ~0x100000; ++ WREG32(VCE_CLOCK_GATING_B, tmp); ++} ++ + int vce_v2_0_resume(struct radeon_device *rdev) + { + uint64_t addr = rdev->vce.gpu_addr; +@@ -66,5 +175,7 @@ int vce_v2_0_resume(struct radeon_device *rdev) + WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, + ~VCE_SYS_INT_TRAP_INTERRUPT_EN); + ++ vce_v2_0_init_cg(rdev); ++ + return 0; + } +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0042-yocto-amd-drm-radeon-cik-enable-disable-vce-cg-when-encoding.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0042-yocto-amd-drm-radeon-cik-enable-disable-vce-cg-when-encoding.patch new file mode 100644 index 00000000..b9b96338 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0042-yocto-amd-drm-radeon-cik-enable-disable-vce-cg-when-encoding.patch @@ -0,0 +1,90 @@ +From c37b6e8a309e0256e0380984ce293594efea71ba Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Fri, 6 Sep 2013 12:33:04 -0400 +Subject: [PATCH 42/44] drm/radeon/cik: enable/disable vce cg when encoding + +Some of the vce clocks are automatic, others need to +be manually enabled. For ease, just disable cg when +vce is active. + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/ci_dpm.c | 7 ++++++- + drivers/gpu/drm/radeon/cik.c | 5 +++++ + drivers/gpu/drm/radeon/kv_dpm.c | 4 ++++ + 3 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c +index a6a2396..14f7192 100644 +--- a/drivers/gpu/drm/radeon/ci_dpm.c ++++ b/drivers/gpu/drm/radeon/ci_dpm.c +@@ -3598,8 +3598,10 @@ static int ci_update_vce_dpm(struct radeon_device *rdev, + + if (radeon_current_state->evclk != radeon_new_state->evclk) { + if (radeon_new_state->evclk) { +- pi->smc_state_table.VceBootLevel = ci_get_vce_boot_level(rdev); ++ /* turn the clocks on when encoding */ ++ cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, false); + ++ pi->smc_state_table.VceBootLevel = ci_get_vce_boot_level(rdev); + tmp = RREG32_SMC(DPM_TABLE_475); + tmp &= ~VceBootLevel_MASK; + tmp |= VceBootLevel(pi->smc_state_table.VceBootLevel); +@@ -3607,6 +3609,9 @@ static int ci_update_vce_dpm(struct radeon_device *rdev, + + ret = ci_enable_vce_dpm(rdev, true); + } else { ++ /* turn the clocks off when not encoding */ ++ cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, true); ++ + ret = ci_enable_vce_dpm(rdev, false); + } + } +diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +index 9af1f3f..5635f04 100644 +--- a/drivers/gpu/drm/radeon/cik.c ++++ b/drivers/gpu/drm/radeon/cik.c +@@ -72,6 +72,7 @@ extern void cik_sdma_vm_set_page(struct radeon_device *rdev, + uint64_t pe, + uint64_t addr, unsigned count, + uint32_t incr, uint32_t flags); ++extern void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable); + static void cik_rlc_stop(struct radeon_device *rdev); + static void cik_pcie_gen3_enable(struct radeon_device *rdev); + static void cik_program_aspm(struct radeon_device *rdev); +@@ -5409,6 +5410,10 @@ void cik_update_cg(struct radeon_device *rdev, + cik_enable_hdp_mgcg(rdev, enable); + cik_enable_hdp_ls(rdev, enable); + } ++ ++ if (block & RADEON_CG_BLOCK_VCE) { ++ vce_v2_0_enable_mgcg(rdev, enable); ++ } + } + + static void cik_init_cg(struct radeon_device *rdev) +diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c +index c8b9d7b..a100b23 100644 +--- a/drivers/gpu/drm/radeon/kv_dpm.c ++++ b/drivers/gpu/drm/radeon/kv_dpm.c +@@ -1420,6 +1420,8 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, + + if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) { + kv_dpm_powergate_vce(rdev, false); ++ /* turn the clocks on when encoding */ ++ cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, false); + if (pi->caps_stable_p_state) + pi->vce_boot_level = table->count - 1; + else +@@ -1442,6 +1444,8 @@ static int kv_update_vce_dpm(struct radeon_device *rdev, + kv_enable_vce_dpm(rdev, true); + } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) { + kv_enable_vce_dpm(rdev, false); ++ /* turn the clocks off when not encoding */ ++ cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, true); + kv_dpm_powergate_vce(rdev, true); + } + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0043-yocto-amd-drm-radeon-fix-CP-semaphores-on-CIK.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0043-yocto-amd-drm-radeon-fix-CP-semaphores-on-CIK.patch new file mode 100644 index 00000000..f054bf3e --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0043-yocto-amd-drm-radeon-fix-CP-semaphores-on-CIK.patch @@ -0,0 +1,117 @@ +From 407373620f1d98d5c36c46c265ee311a1be87cf4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig at amd.com> +Date: Wed, 19 Feb 2014 13:21:35 -0500 +Subject: [PATCH 43/44] drm/radeon: fix CP semaphores on CIK +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Christian König <christian.koenig at amd.com> +--- + drivers/gpu/drm/radeon/radeon.h | 4 +++- + drivers/gpu/drm/radeon/radeon_ring.c | 2 +- + drivers/gpu/drm/radeon/radeon_semaphore.c | 19 ++++++++++++++++--- + 3 files changed, 20 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h +index f3a4f34..1044268 100644 +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -137,6 +137,9 @@ extern int radeon_aspm; + /* max number of rings */ + #define RADEON_NUM_RINGS 8 + ++/* number of hw syncs before falling back on blocking */ ++#define RADEON_NUM_SYNCS 4 ++ + /* hardcode those limit for now */ + #define RADEON_VA_IB_OFFSET (1 << 20) + #define RADEON_VA_RESERVED_SIZE (8 << 20) +@@ -553,7 +556,6 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, + /* + * Semaphores. + */ +-/* everything here is constant */ + struct radeon_semaphore { + struct radeon_sa_bo *sa_bo; + signed waiters; +diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c +index 91457f8..529893f 100644 +--- a/drivers/gpu/drm/radeon/radeon_ring.c ++++ b/drivers/gpu/drm/radeon/radeon_ring.c +@@ -139,7 +139,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, + } + + /* 64 dwords should be enough for fence too */ +- r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_RINGS * 8); ++ r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_SYNCS * 8); + if (r) { + dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); + return r; +diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c +index 2b42aa1..9006b32 100644 +--- a/drivers/gpu/drm/radeon/radeon_semaphore.c ++++ b/drivers/gpu/drm/radeon/radeon_semaphore.c +@@ -34,14 +34,15 @@ + int radeon_semaphore_create(struct radeon_device *rdev, + struct radeon_semaphore **semaphore) + { ++ uint32_t *cpu_addr; + int i, r; + + *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); + if (*semaphore == NULL) { + return -ENOMEM; + } +- r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, +- &(*semaphore)->sa_bo, 8, 8, true); ++ r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &(*semaphore)->sa_bo, ++ 8 * RADEON_NUM_SYNCS, 8, true); + if (r) { + kfree(*semaphore); + *semaphore = NULL; +@@ -49,7 +50,10 @@ int radeon_semaphore_create(struct radeon_device *rdev, + } + (*semaphore)->waiters = 0; + (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); +- *((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; ++ ++ cpu_addr = radeon_sa_bo_cpu_addr((*semaphore)->sa_bo); ++ for (i = 0; i < RADEON_NUM_SYNCS; ++i) ++ cpu_addr[i] = 0; + + for (i = 0; i < RADEON_NUM_RINGS; ++i) + (*semaphore)->sync_to[i] = NULL; +@@ -125,6 +129,7 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, + struct radeon_semaphore *semaphore, + int ring) + { ++ unsigned count = 0; + int i, r; + + for (i = 0; i < RADEON_NUM_RINGS; ++i) { +@@ -140,6 +145,12 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, + return -EINVAL; + } + ++ if (++count > RADEON_NUM_SYNCS) { ++ /* not enough room, wait manually */ ++ radeon_fence_wait_locked(fence); ++ continue; ++ } ++ + /* allocate enough space for sync command */ + r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); + if (r) { +@@ -164,6 +175,8 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, + + radeon_ring_commit(rdev, &rdev->ring[i]); + radeon_fence_note_sync(fence, ring); ++ ++ semaphore->gpu_addr += 8; + } + + return 0; +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0044-yocto-amd-drm-radeon-disable-dynamic-powering-vce.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0044-yocto-amd-drm-radeon-disable-dynamic-powering-vce.patch new file mode 100644 index 00000000..b2bb83ce --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0044-yocto-amd-drm-radeon-disable-dynamic-powering-vce.patch @@ -0,0 +1,30 @@ +From 83e62f79352aa190927cd9769493ac50291bef86 Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Mon, 24 Feb 2014 12:55:11 -0500 +Subject: [PATCH 44/44] drm/radeon: disable dynamic powering vce + +--- + drivers/gpu/drm/radeon/radeon_vce.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c +index eb11ac0..5bfb726 100644 +--- a/drivers/gpu/drm/radeon/radeon_vce.c ++++ b/drivers/gpu/drm/radeon/radeon_vce.c +@@ -245,11 +245,11 @@ static void radeon_vce_idle_work_handler(struct work_struct *work) + + if ((radeon_fence_count_emitted(rdev, TN_RING_TYPE_VCE1_INDEX) == 0) && + (radeon_fence_count_emitted(rdev, TN_RING_TYPE_VCE2_INDEX) == 0)) { +- if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { ++ /*if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { + radeon_dpm_enable_vce(rdev, false); + } else { + radeon_set_vce_clocks(rdev, 0, 0); +- } ++ }*/ + } else { + schedule_delayed_work(&rdev->vce.idle_work, + msecs_to_jiffies(VCE_IDLE_TIMEOUT_MS)); +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0045-yocto-amd-drm-radeon-add-Mullins-chip-family.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0045-yocto-amd-drm-radeon-add-Mullins-chip-family.patch new file mode 100644 index 00000000..beb1d5c8 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0045-yocto-amd-drm-radeon-add-Mullins-chip-family.patch @@ -0,0 +1,39 @@ +drm/radeon: add Mullins chip family + +Mullins is a new CI-based APU. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +diff -Naur a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c +--- a/drivers/gpu/drm/radeon/radeon_asic.c 2014-04-26 01:51:28.161070642 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_asic.c 2014-04-26 01:58:12.613084276 +0530 +@@ -2484,6 +2484,7 @@ + break; + case CHIP_KAVERI: + case CHIP_KABINI: ++ case CHIP_MULLINS: + rdev->asic = &kv_asic; + /* set num crtcs */ + if (rdev->family == CHIP_KAVERI) { +diff -Naur a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c +--- a/drivers/gpu/drm/radeon/radeon_device.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_device.c 2014-04-26 01:59:11.645085768 +0530 +@@ -98,6 +98,7 @@ + "BONAIRE", + "KAVERI", + "KABINI", ++ "MULLINS", + "LAST", + }; + +diff -Naur a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h +--- a/drivers/gpu/drm/radeon/radeon_family.h 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_family.h 2014-04-26 01:59:38.813087463 +0530 +@@ -96,6 +96,7 @@ + CHIP_BONAIRE, + CHIP_KAVERI, + CHIP_KABINI, ++ CHIP_MULLINS, + CHIP_LAST, + }; + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0046-yocto-amd-drm-radeon-update-cik-init-for-Mullins.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0046-yocto-amd-drm-radeon-update-cik-init-for-Mullins.patch new file mode 100644 index 00000000..3f63009e --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0046-yocto-amd-drm-radeon-update-cik-init-for-Mullins.patch @@ -0,0 +1,140 @@ +drm/radeon: update cik init for Mullins. + +Also add golden registers, update firmware loading functions. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +diff -Naur a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c +--- a/drivers/gpu/drm/radeon/cik.c 2014-04-26 01:53:33.429065903 +0530 ++++ b/drivers/gpu/drm/radeon/cik.c 2014-04-26 02:11:35.265111552 +0530 +@@ -53,6 +53,12 @@ + MODULE_FIRMWARE("radeon/KABINI_mec.bin"); + MODULE_FIRMWARE("radeon/KABINI_rlc.bin"); + MODULE_FIRMWARE("radeon/KABINI_sdma.bin"); ++MODULE_FIRMWARE("radeon/MULLINS_pfp.bin"); ++MODULE_FIRMWARE("radeon/MULLINS_me.bin"); ++MODULE_FIRMWARE("radeon/MULLINS_ce.bin"); ++MODULE_FIRMWARE("radeon/MULLINS_mec.bin"); ++MODULE_FIRMWARE("radeon/MULLINS_rlc.bin"); ++MODULE_FIRMWARE("radeon/MULLINS_sdma.bin"); + + extern int r600_ih_ring_alloc(struct radeon_device *rdev); + extern void r600_ih_ring_fini(struct radeon_device *rdev); +@@ -1303,6 +1309,43 @@ + 0xd80c, 0xff000ff0, 0x00000100 + }; + ++static const u32 godavari_golden_registers[] = ++{ ++ 0x55e4, 0xff607fff, 0xfc000100, ++ 0x6ed8, 0x00010101, 0x00010000, ++ 0x9830, 0xffffffff, 0x00000000, ++ 0x98302, 0xf00fffff, 0x00000400, ++ 0x6130, 0xffffffff, 0x00010000, ++ 0x5bb0, 0x000000f0, 0x00000070, ++ 0x5bc0, 0xf0311fff, 0x80300000, ++ 0x98f8, 0x73773777, 0x12010001, ++ 0x98fc, 0xffffffff, 0x00000010, ++ 0x8030, 0x00001f0f, 0x0000100a, ++ 0x2f48, 0x73773777, 0x12010001, ++ 0x2408, 0x000fffff, 0x000c007f, ++ 0x8a14, 0xf000003f, 0x00000007, ++ 0x8b24, 0xffffffff, 0x00ff0fff, ++ 0x30a04, 0x0000ff0f, 0x00000000, ++ 0x28a4c, 0x07ffffff, 0x06000000, ++ 0x4d8, 0x00000fff, 0x00000100, ++ 0xd014, 0x00010000, 0x00810001, ++ 0xd814, 0x00010000, 0x00810001, ++ 0x3e78, 0x00000001, 0x00000002, ++ 0xc768, 0x00000008, 0x00000008, ++ 0xc770, 0x00000f00, 0x00000800, ++ 0xc774, 0x00000f00, 0x00000800, ++ 0xc798, 0x00ffffff, 0x00ff7fbf, ++ 0xc79c, 0x00ffffff, 0x00ff7faf, ++ 0x8c00, 0x000000ff, 0x00000001, ++ 0x214f8, 0x01ff01ff, 0x00000002, ++ 0x21498, 0x007ff800, 0x00200000, ++ 0x2015c, 0xffffffff, 0x00000f40, ++ 0x88c4, 0x001f3ae3, 0x00000082, ++ 0x88d4, 0x0000001f, 0x00000010, ++ 0x30934, 0xffffffff, 0x00000000 ++}; ++ ++ + static void cik_init_golden_registers(struct radeon_device *rdev) + { + switch (rdev->family) { +@@ -1334,6 +1377,20 @@ + kalindi_golden_spm_registers, + (const u32)ARRAY_SIZE(kalindi_golden_spm_registers)); + break; ++ case CHIP_MULLINS: ++ radeon_program_register_sequence(rdev, ++ kalindi_mgcg_cgcg_init, ++ (const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init)); ++ radeon_program_register_sequence(rdev, ++ godavari_golden_registers, ++ (const u32)ARRAY_SIZE(godavari_golden_registers)); ++ radeon_program_register_sequence(rdev, ++ kalindi_golden_common_registers, ++ (const u32)ARRAY_SIZE(kalindi_golden_common_registers)); ++ radeon_program_register_sequence(rdev, ++ kalindi_golden_spm_registers, ++ (const u32)ARRAY_SIZE(kalindi_golden_spm_registers)); ++ break; + case CHIP_KAVERI: + radeon_program_register_sequence(rdev, + spectre_mgcg_cgcg_init, +@@ -1602,6 +1659,15 @@ + rlc_req_size = KB_RLC_UCODE_SIZE * 4; + sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; + break; ++ case CHIP_MULLINS: ++ chip_name = "MULLINS"; ++ pfp_req_size = CIK_PFP_UCODE_SIZE * 4; ++ me_req_size = CIK_ME_UCODE_SIZE * 4; ++ ce_req_size = CIK_CE_UCODE_SIZE * 4; ++ mec_req_size = CIK_MEC_UCODE_SIZE * 4; ++ rlc_req_size = ML_RLC_UCODE_SIZE * 4; ++ sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; ++ break; + default: BUG(); + } + +@@ -2769,6 +2835,7 @@ + gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; + break; + case CHIP_KABINI: ++ case CHIP_MULLINS: + default: + rdev->config.cik.max_shader_engines = 1; + rdev->config.cik.max_tile_pipes = 2; +@@ -5039,6 +5106,9 @@ + case CHIP_KABINI: + size = KB_RLC_UCODE_SIZE; + break; ++ case CHIP_MULLINS: ++ size = ML_RLC_UCODE_SIZE; ++ break; + } + + cik_rlc_stop(rdev); +@@ -5786,6 +5856,7 @@ + buffer[count++] = 0x00000000; + break; + case CHIP_KABINI: ++ case CHIP_MULLINS: + buffer[count++] = 0x00000000; /* XXX */ + buffer[count++] = 0x00000000; + break; +diff -Naur a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h +--- a/drivers/gpu/drm/radeon/radeon_ucode.h 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_ucode.h 2014-04-26 02:12:27.753109445 +0530 +@@ -52,6 +52,7 @@ + #define BONAIRE_RLC_UCODE_SIZE 2048 + #define KB_RLC_UCODE_SIZE 2560 + #define KV_RLC_UCODE_SIZE 2560 ++#define ML_RLC_UCODE_SIZE 2560 + + /* MC */ + #define BTC_MC_UCODE_SIZE 6024 diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0047-yocto-amd-drm-radeon-add-Mullins-UVD-support.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0047-yocto-amd-drm-radeon-add-Mullins-UVD-support.patch new file mode 100644 index 00000000..0529e3c0 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0047-yocto-amd-drm-radeon-add-Mullins-UVD-support.patch @@ -0,0 +1,17 @@ +drm/radeon/: add Mullins UVD support. + +Has same version of UVD as other CIK parts. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +diff -Naur a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c +--- a/drivers/gpu/drm/radeon/radeon_uvd.c 2014-04-26 01:50:28.941068710 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_uvd.c 2014-04-26 02:15:33.177108251 +0530 +@@ -98,6 +98,7 @@ + case CHIP_BONAIRE: + case CHIP_KABINI: + case CHIP_KAVERI: ++ case CHIP_MULLINS: + fw_name = FIRMWARE_BONAIRE; + break; + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0048-yocto-amd-drm-radeon-add-Mullins-dpm-support.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0048-yocto-amd-drm-radeon-add-Mullins-dpm-support.patch new file mode 100644 index 00000000..001df0a7 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0048-yocto-amd-drm-radeon-add-Mullins-dpm-support.patch @@ -0,0 +1,111 @@ +drm/radeon: add Mullins dpm support. + +Generic dpm support similar to Kabini. Mullins specific features +will be worked on later. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +diff -Naur a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c +--- a/drivers/gpu/drm/radeon/kv_dpm.c 2014-04-26 01:53:33.433066497 +0530 ++++ b/drivers/gpu/drm/radeon/kv_dpm.c 2014-04-26 02:25:06.745138697 +0530 +@@ -639,7 +639,7 @@ + + static int kv_unforce_levels(struct radeon_device *rdev) + { +- if (rdev->family == CHIP_KABINI) ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) + return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel); + else + return kv_set_enabled_levels(rdev); +@@ -1625,7 +1625,7 @@ + if (pi->acp_power_gated == gate) + return; + +- if (rdev->family == CHIP_KABINI) ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) + return; + + pi->acp_power_gated = gate; +@@ -1799,7 +1799,7 @@ + } + } + +- if (rdev->family == CHIP_KABINI) { ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) { + if (pi->enable_dpm) { + kv_set_valid_clock_range(rdev, new_ps); + kv_update_dfs_bypass_settings(rdev, new_ps); +@@ -1880,7 +1880,7 @@ + { + struct kv_power_info *pi = kv_get_pi(rdev); + +- if (rdev->family == CHIP_KABINI) { ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) { + kv_force_lowest_valid(rdev); + kv_init_graphics_levels(rdev); + kv_program_bootup_state(rdev); +@@ -1959,7 +1959,7 @@ + break; + } + +- if (rdev->family == CHIP_KABINI) ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) + return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); + else + return kv_set_enabled_level(rdev, i); +@@ -1979,7 +1979,7 @@ + break; + } + +- if (rdev->family == CHIP_KABINI) ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) + return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); + else + return kv_set_enabled_level(rdev, i); +@@ -2136,7 +2136,7 @@ + else + pi->battery_state = false; + +- if (rdev->family == CHIP_KABINI) { ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) { + ps->dpm0_pg_nb_ps_lo = 0x1; + ps->dpm0_pg_nb_ps_hi = 0x0; + ps->dpmx_nb_ps_lo = 0x1; +@@ -2197,7 +2197,7 @@ + if (pi->lowest_valid > pi->highest_valid) + return -EINVAL; + +- if (rdev->family == CHIP_KABINI) { ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) { + for (i = pi->lowest_valid; i <= pi->highest_valid; i++) { + pi->graphics_level[i].GnbSlow = 1; + pi->graphics_level[i].ForceNbPs1 = 0; +@@ -2342,7 +2342,7 @@ + struct kv_power_info *pi = kv_get_pi(rdev); + u32 nbdpmconfig1; + +- if (rdev->family == CHIP_KABINI) ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) + return; + + if (pi->sys_info.nb_dpm_enable) { +@@ -2649,7 +2649,7 @@ + + pi->sram_end = SMC_RAM_END; + +- if (rdev->family == CHIP_KABINI) ++ if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) + pi->high_voltage_t = 4001; + + pi->enable_nb_dpm = true; +diff -Naur a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c +--- a/drivers/gpu/drm/radeon/radeon_pm.c 2014-04-26 01:51:53.857071705 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_pm.c 2014-04-26 02:25:52.577153751 +0530 +@@ -1298,6 +1298,7 @@ + case CHIP_BONAIRE: + case CHIP_KABINI: + case CHIP_KAVERI: ++ case CHIP_MULLINS: + /* DPM requires the RLC, RV770+ dGPU requires SMC */ + if (!rdev->rlc_fw) + rdev->pm.pm_method = PM_METHOD_PROFILE; diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0049-yocto-amd-drm-radeon-modesetting-updates-for-Mullins.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0049-yocto-amd-drm-radeon-modesetting-updates-for-Mullins.patch new file mode 100644 index 00000000..7b21e922 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0049-yocto-amd-drm-radeon-modesetting-updates-for-Mullins.patch @@ -0,0 +1,21 @@ +drm/radeon: modesetting updates for Mullins. + +Uses the same code as Kabini. + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +diff -Naur a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c +--- a/drivers/gpu/drm/radeon/atombios_crtc.c 2014-04-26 01:50:23.277068059 +0530 ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c 2014-04-26 02:30:34.765161214 +0530 +@@ -1689,8 +1689,9 @@ + } + /* otherwise, pick one of the plls */ + if ((rdev->family == CHIP_KAVERI) || +- (rdev->family == CHIP_KABINI)) { +- /* KB/KV has PPLL1 and PPLL2 */ ++ (rdev->family == CHIP_KABINI) || ++ (rdev->family == CHIP_MULLINS)) { ++ /* KB/KV/ML has PPLL1 and PPLL2 */ + pll_in_use = radeon_get_pll_use_mask(crtc); + if (!(pll_in_use & (1 << ATOM_PPLL2))) + return ATOM_PPLL2; diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0050-yocto-amd-drm-radeon-add-pci-ids-for-Mullins.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0050-yocto-amd-drm-radeon-add-pci-ids-for-Mullins.patch new file mode 100644 index 00000000..daf70386 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0050-yocto-amd-drm-radeon-add-pci-ids-for-Mullins.patch @@ -0,0 +1,30 @@ +drm/radeon: add pci ids for Mullins + +Signed-off-by: Samuel Li <samuel.li@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +diff -Naur a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +--- a/include/drm/drm_pciids.h 2013-11-04 05:11:51.000000000 +0530 ++++ b/include/drm/drm_pciids.h 2014-04-26 02:41:24.721174148 +0530 +@@ -625,6 +625,22 @@ + {0x1002, 0x983d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x983e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x983f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9851, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9852, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9853, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9854, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9855, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9856, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9857, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9858, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9859, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x985A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x985B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x985C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x985D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x985E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0051-yocto-amd-drm-radeon-add-Mulins-VCE-support.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0051-yocto-amd-drm-radeon-add-Mulins-VCE-support.patch new file mode 100644 index 00000000..b46eaa73 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0051-yocto-amd-drm-radeon-add-Mulins-VCE-support.patch @@ -0,0 +1,17 @@ +From 0b42c7cafb1f0f836c26dd5f0309d400a3b33740 Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Mon, 28 Apr 2014 15:44:55 -0400 +Subject: [PATCH] drm/radeon: add Mulins VCE support + +Signed-off-by: Leo Liu <leo.liu@amd.com> +diff -Naur a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c +--- a/drivers/gpu/drm/radeon/radeon_vce.c 2014-04-29 15:47:47.888192142 +0530 ++++ b/drivers/gpu/drm/radeon/radeon_vce.c 2014-04-29 15:50:44.172184659 +0530 +@@ -67,6 +67,7 @@ + case CHIP_BONAIRE: + case CHIP_KAVERI: + case CHIP_KABINI: ++ case CHIP_MULLINS: + fw_name = FIRMWARE_BONAIRE; + break; + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0052-yocto-amd-clear-exceptions-in-AMD-FXSAVE-workaround.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0052-yocto-amd-clear-exceptions-in-AMD-FXSAVE-workaround.patch new file mode 100644 index 00000000..ccc0d73a --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0052-yocto-amd-clear-exceptions-in-AMD-FXSAVE-workaround.patch @@ -0,0 +1,34 @@ +Backport of commit id 26bef1318adc1b3a530ecc807ef99346db2aa8b0 to kernel 3.12 + +Before we do an EMMS in the AMD FXSAVE information leak workaround we +need to clear any pending exceptions, otherwise we trap with a +floating-point exception inside this code. + +Reported-by: halfdog <me@halfdog.net> +Tested-by: Borislav Petkov <bp@suse.de> +Link: http://lkml.kernel.org/r/CA%2B55aFxQnY_PCG_n4=0w-VG=YLXL-yr7oMxyy0WU2gCBAf3ydg@mail.gmail.com +Signed-off-by: H. Peter Anvin <hpa@zytor.com> +Signed-off-by: Arindam Nath <arindam.nath@amd.com> +diff -Naur a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h +--- a/arch/x86/include/asm/fpu-internal.h 2013-11-04 05:11:51.000000000 +0530 ++++ b/arch/x86/include/asm/fpu-internal.h 2014-04-09 16:51:26.665126690 +0530 +@@ -293,12 +293,13 @@ + /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception + is pending. Clear the x87 state here by setting it to fixed + values. "m" is a random variable that should be in L1 */ +- alternative_input( +- ASM_NOP8 ASM_NOP2, +- "emms\n\t" /* clear stack tags */ +- "fildl %P[addr]", /* set F?P to defined value */ +- X86_FEATURE_FXSAVE_LEAK, +- [addr] "m" (tsk->thread.fpu.has_fpu)); ++ if (unlikely(static_cpu_has(X86_FEATURE_FXSAVE_LEAK))) { ++ asm volatile( ++ "fnclex\n\t" ++ "emms\n\t" ++ "fildl %P[addr]" /* set F?P to defined value */ ++ : : [addr] "m" (tsk->thread.fpu.has_fpu)); ++ } + + return fpu_restore_checking(&tsk->thread.fpu); + } diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0053-yocto-amd-i2c-piix4-add-support-for-AMD-ML-and-CZ-SMBus-changes.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0053-yocto-amd-i2c-piix4-add-support-for-AMD-ML-and-CZ-SMBus-changes.patch new file mode 100644 index 00000000..556e5806 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0053-yocto-amd-i2c-piix4-add-support-for-AMD-ML-and-CZ-SMBus-changes.patch @@ -0,0 +1,87 @@ +Backport of commit id 032f708bc4f6da868ec49dac48ddf3670d8035d3 + +i2c: piix4: Add support for AMD ML and CZ SMBus changes + +The locations of SMBus register base address and enablement bit are changed +from AMD ML, which need this patch to be supported. + +Signed-off-by: Shane Huang <shane.huang@amd.com> +Reviewed-by: Jean Delvare <khali@linux-fr.org> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +Cc: stable@vger.kernel.org +Signed-off-by: Arindam Nath <arindam.nath@amd.com> +diff -Naur a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c +--- a/drivers/i2c/busses/i2c-piix4.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/i2c/busses/i2c-piix4.c 2014-05-06 22:03:36.945675193 +0530 +@@ -22,7 +22,7 @@ + Intel PIIX4, 440MX + Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 + ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800 +- AMD Hudson-2, CZ ++ AMD Hudson-2, ML, CZ + SMSC Victory66 + + Note: we assume there can only be one device, with one or more +@@ -235,7 +235,8 @@ + { + unsigned short piix4_smba; + unsigned short smba_idx = 0xcd6; +- u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en; ++ u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status; ++ u8 i2ccfg, i2ccfg_offset = 0x10; + + /* SB800 and later SMBus does not support forcing address */ + if (force || force_addr) { +@@ -245,7 +246,15 @@ + } + + /* Determine the address of the SMBus areas */ +- smb_en = (aux) ? 0x28 : 0x2c; ++ if ((PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && ++ PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && ++ PIIX4_dev->revision >= 0x41) || ++ (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && ++ PIIX4_dev->device == 0x790b && ++ PIIX4_dev->revision >= 0x49)) ++ smb_en = 0x00; ++ else ++ smb_en = (aux) ? 0x28 : 0x2c; + + if (!request_region(smba_idx, 2, "smba_idx")) { + dev_err(&PIIX4_dev->dev, "SMBus base address index region " +@@ -258,13 +267,22 @@ + smba_en_hi = inb_p(smba_idx + 1); + release_region(smba_idx, 2); + +- if ((smba_en_lo & 1) == 0) { ++ if (!smb_en) { ++ smb_en_status = smba_en_lo & 0x10; ++ piix4_smba = smba_en_hi << 8; ++ if (aux) ++ piix4_smba |= 0x20; ++ } else { ++ smb_en_status = smba_en_lo & 0x01; ++ piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; ++ } ++ ++ if (!smb_en_status) { + dev_err(&PIIX4_dev->dev, + "Host SMBus controller not enabled!\n"); + return -ENODEV; + } + +- piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; + if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) + return -ENODEV; + +diff -Naur a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +--- a/drivers/i2c/busses/Kconfig 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/i2c/busses/Kconfig 2014-05-06 21:47:27.557717841 +0530 +@@ -151,6 +151,7 @@ + ATI SB700/SP5100 + ATI SB800 + AMD Hudson-2 ++ AMD ML + AMD CZ + Serverworks OSB4 + Serverworks CSB5 diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0054-yocto-amd-i2c-piix4-use-different-message-for-AMD-auxiliary-SMBus-controller.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0054-yocto-amd-i2c-piix4-use-different-message-for-AMD-auxiliary-SMBus-controller.patch new file mode 100644 index 00000000..7808bdcf --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0054-yocto-amd-i2c-piix4-use-different-message-for-AMD-auxiliary-SMBus-controller.patch @@ -0,0 +1,24 @@ +Backport of commit id 85fd0fe6fc002deba03fe36c1c9726cde1e6331c + +i2c: piix4: Use different message for AMD Auxiliary SMBus Controller + +Same messages for AMD main and auxiliary SMBus controllers lead to confusion, +this patch is to remove confusion and keep consistent with non-AMD products. + +Signed-off-by: Shane Huang <shane.huang@amd.com> +Reviewed-by: Jean Delvare <khali@linux-fr.org> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +Signed-off-by: Arindam Nath <arindam.nath@amd.com> +diff -Naur a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c +--- a/drivers/i2c/busses/i2c-piix4.c 2014-05-06 22:10:41.501656511 +0530 ++++ b/drivers/i2c/busses/i2c-piix4.c 2014-05-06 22:12:26.333651900 +0530 +@@ -295,7 +295,8 @@ + /* Aux SMBus does not support IRQ information */ + if (aux) { + dev_info(&PIIX4_dev->dev, +- "SMBus Host Controller at 0x%x\n", piix4_smba); ++ "Auxiliary SMBus Host Controller at 0x%x\n", ++ piix4_smba); + return piix4_smba; + } + diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0055-yocto-amd-change-acpi-enforce-resources-to-lax.patch b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0055-yocto-amd-change-acpi-enforce-resources-to-lax.patch new file mode 100644 index 00000000..cf5be6c8 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/0055-yocto-amd-change-acpi-enforce-resources-to-lax.patch @@ -0,0 +1,19 @@ +On some AMD platforms, the SMBus IO region 0xb00 - 0xb07 conflicts with the +corresponding ACPI SystemIO region. This prevents the SMBus host controller +driver to function correctly. We set acpi_enforce_resources to +ENFORCE_RESOURCES_LAX so that the SMBus driver can work normally, even +though a warning message notifying the conflict is printed in system logs. + +Signed-off-by: Arindam Nath <arindam.nath@amd.com> +diff -Naur a/drivers/acpi/osl.c b/drivers/acpi/osl.c +--- a/drivers/acpi/osl.c 2013-11-04 05:11:51.000000000 +0530 ++++ b/drivers/acpi/osl.c 2014-05-06 16:41:51.078524581 +0530 +@@ -1533,7 +1533,7 @@ + #define ENFORCE_RESOURCES_LAX 1 + #define ENFORCE_RESOURCES_NO 0 + +-static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT; ++static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_LAX; + + static int __init acpi_enforce_resources_setup(char *str) + { diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto/defconfig b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/defconfig new file mode 100644 index 00000000..fef542cd --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto/defconfig @@ -0,0 +1,4181 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/x86 3.12.0 Kernel Configuration +# +CONFIG_64BIT=y +CONFIG_X86_64=y +CONFIG_X86=y +CONFIG_INSTRUCTION_DECODER=y +CONFIG_OUTPUT_FORMAT="elf64-x86-64" +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_MMU=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_AUTOPROBE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ZONE_DMA32=y +CONFIG_AUDIT_ARCH=y +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_X86_64_SMP=y +CONFIG_X86_HT=y +CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" +CONFIG_ARCH_CPU_PROBE_RELEASE=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="-yocto-standard" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_FHANDLE=y +# CONFIG_AUDIT is not set + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y +CONFIG_GENERIC_CMOS_UPDATE=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +CONFIG_RCU_STALL_COMMON=y +# CONFIG_RCU_USER_QS is not set +CONFIG_RCU_FANOUT=64 +CONFIG_RCU_FANOUT_LEAF=16 +# CONFIG_RCU_FANOUT_EXACT is not set +CONFIG_RCU_FAST_NO_HZ=y +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +# CONFIG_RCU_NOCB_CPU is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANTS_PROT_NUMA_PROT_NONE=y +# CONFIG_NUMA_BALANCING is not set +CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_SWAP_ENABLED=y +CONFIG_MEMCG_KMEM=y +# CONFIG_CGROUP_HUGETLB is not set +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_CFS_BANDWIDTH is not set +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +CONFIG_UIDGID_STRICT_TYPE_CHECKS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_MM_OWNER=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_HAVE_PCSPKR_PLATFORM=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_PCI_QUIRKS=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLUB_CPU_PARTIAL=y +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=y +# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set +CONFIG_HAVE_OPROFILE=y +CONFIG_OPROFILE_NMI_TIMER=y +CONFIG_KPROBES=y +# CONFIG_JUMP_LABEL is not set +CONFIG_KPROBES_ON_FTRACE=y +CONFIG_UPROBES=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_KRETPROBES=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_KPROBES_ON_FTRACE=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y +CONFIG_HAVE_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_PERF_EVENTS_NMI=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_SOFT_DIRTY=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +# CONFIG_MODULE_SIG is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_THROTTLING=y +# CONFIG_BLK_CMDLINE_PARSER is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_UNINLINE_SPIN_UNLOCK=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# Processor type and features +# +CONFIG_ZONE_DMA=y +CONFIG_SMP=y +# CONFIG_X86_X2APIC is not set +CONFIG_X86_MPPARSE=y +CONFIG_X86_EXTENDED_PLATFORM=y +# CONFIG_X86_VSMP is not set +# CONFIG_X86_INTEL_LPSS is not set +CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +# CONFIG_HYPERVISOR_GUEST is not set +CONFIG_NO_BOOTMEM=y +# CONFIG_MEMTEST is not set +# CONFIG_MK8 is not set +# CONFIG_MPSC is not set +CONFIG_MCORE2=y +# CONFIG_MATOM is not set +# CONFIG_GENERIC_CPU is not set +CONFIG_X86_INTERNODE_CACHE_SHIFT=6 +CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_P6_NOP=y +CONFIG_X86_TSC=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_PROCESSOR_SELECT=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR=y +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_DMI=y +CONFIG_GART_IOMMU=y +CONFIG_CALGARY_IOMMU=y +CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +# CONFIG_MAXSMP is not set +CONFIG_NR_CPUS=24 +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_MCE=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y +CONFIG_X86_MCE_THRESHOLD=y +CONFIG_X86_MCE_INJECT=m +CONFIG_X86_THERMAL_VECTOR=y +# CONFIG_I8K is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MICROCODE_INTEL_LIB=y +# CONFIG_MICROCODE_INTEL_EARLY is not set +# CONFIG_MICROCODE_AMD_EARLY is not set +CONFIG_X86_MSR=m +CONFIG_X86_CPUID=m +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_DIRECT_GBPAGES=y +CONFIG_NUMA=y +CONFIG_AMD_NUMA=y +CONFIG_X86_64_ACPI_NUMA=y +CONFIG_NODES_SPAN_OTHER_NODES=y +# CONFIG_NUMA_EMU is not set +CONFIG_NODES_SHIFT=6 +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +# CONFIG_MOVABLE_NODE is not set +CONFIG_HAVE_BOOTMEM_INFO_NODE=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTPLUG_SPARSE=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_BALLOON_COMPACTION=y +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_NEED_BOUNCE_POOL=y +CONFIG_VIRT_TO_BUS=y +CONFIG_MMU_NOTIFIER=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +CONFIG_MEMORY_FAILURE=y +# CONFIG_HWPOISON_INJECT is not set +CONFIG_TRANSPARENT_HUGEPAGE=y +# CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set +CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +# CONFIG_CMA is not set +# CONFIG_ZBUD is not set +# CONFIG_ZSWAP is not set +# CONFIG_MEM_SOFT_DIRTY is not set +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_RESERVE_LOW=64 +CONFIG_MTRR=y +# CONFIG_MTRR_SANITIZER is not set +CONFIG_X86_PAT=y +CONFIG_ARCH_USES_PG_UNCACHED=y +CONFIG_ARCH_RANDOM=y +CONFIG_X86_SMAP=y +CONFIG_EFI=y +CONFIG_EFI_STUB=y +CONFIG_SECCOMP=y +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_HZ_1000=y +CONFIG_HZ=1000 +CONFIG_SCHED_HRTICK=y +CONFIG_KEXEC=y +CONFIG_CRASH_DUMP=y +# CONFIG_KEXEC_JUMP is not set +CONFIG_PHYSICAL_START=0x1000000 +CONFIG_RELOCATABLE=y +CONFIG_PHYSICAL_ALIGN=0x1000000 +CONFIG_HOTPLUG_CPU=y +# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set +# CONFIG_DEBUG_HOTPLUG_CPU0 is not set +CONFIG_COMPAT_VDSO=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_USE_PERCPU_NUMA_NODE_ID=y + +# +# Power management and ACPI options +# +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_PM_SLEEP_DEBUG=y +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_ACPI=y +CONFIG_ACPI_SLEEP=y +# CONFIG_ACPI_PROCFS is not set +# CONFIG_ACPI_PROCFS_POWER is not set +# CONFIG_ACPI_EC_DEBUGFS is not set +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_FAN=y +# CONFIG_ACPI_DOCK is not set +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_HOTPLUG_CPU=y +# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_NUMA=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +# CONFIG_ACPI_INITRD_TABLE_OVERRIDE is not set +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set +# CONFIG_ACPI_PCI_SLOT is not set +CONFIG_X86_PM_TIMER=y +CONFIG_ACPI_CONTAINER=y +# CONFIG_ACPI_HOTPLUG_MEMORY is not set +CONFIG_ACPI_SBS=m +CONFIG_ACPI_HED=y +# CONFIG_ACPI_CUSTOM_METHOD is not set +CONFIG_ACPI_BGRT=y +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_PCIEAER=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +CONFIG_ACPI_APEI_EINJ=m +CONFIG_ACPI_APEI_ERST_DEBUG=m +CONFIG_SFI=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y + +# +# x86 CPU frequency scaling drivers +# +# CONFIG_X86_INTEL_PSTATE is not set +CONFIG_X86_PCC_CPUFREQ=m +CONFIG_X86_ACPI_CPUFREQ=y +CONFIG_X86_ACPI_CPUFREQ_CPB=y +CONFIG_X86_POWERNOW_K8=y +# CONFIG_X86_AMD_FREQ_SENSITIVITY is not set +CONFIG_X86_SPEEDSTEP_CENTRINO=y +CONFIG_X86_P4_CLOCKMOD=m + +# +# shared options +# +CONFIG_X86_SPEEDSTEP_LIB=m + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set +CONFIG_INTEL_IDLE=y + +# +# Memory power savings +# +# CONFIG_I7300_IDLE is not set + +# +# Bus options (PCI etc.) +# +CONFIG_PCI=y +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_CNB20LE_QUIRK is not set +CONFIG_PCIEPORTBUS=y +# CONFIG_HOTPLUG_PCI_PCIE is not set +CONFIG_PCIEAER=y +# CONFIG_PCIE_ECRC is not set +# CONFIG_PCIEAER_INJECT is not set +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEBUG is not set +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_PERFORMANCE is not set +CONFIG_PCIE_PME=y +CONFIG_PCI_MSI=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_REALLOC_ENABLE_AUTO=y +CONFIG_PCI_STUB=m +CONFIG_HT_IRQ=y +CONFIG_PCI_ATS=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PRI=y +CONFIG_PCI_PASID=y +# CONFIG_PCI_IOAPIC is not set +CONFIG_PCI_LABEL=y + +# +# PCI host controller drivers +# +CONFIG_ISA_DMA_API=y +CONFIG_AMD_NB=y +# CONFIG_PCCARD is not set +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_ACPI is not set +CONFIG_HOTPLUG_PCI_CPCI=y +# CONFIG_HOTPLUG_PCI_CPCI_ZT5550 is not set +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_RAPIDIO is not set +CONFIG_X86_SYSFB=y + +# +# Executable file formats / Emulations +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=m +CONFIG_COREDUMP=y +CONFIG_IA32_EMULATION=y +# CONFIG_IA32_AOUT is not set +# CONFIG_X86_X32 is not set +CONFIG_COMPAT=y +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_KEYS_COMPAT=y +CONFIG_X86_DEV_DMA_OPS=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +CONFIG_XFRM=y +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_USER=m +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=y +CONFIG_IP_MROUTE=y +# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +# CONFIG_NET_IPVTI is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_UDP_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +CONFIG_IPV6_ROUTER_PREF=y +# CONFIG_IPV6_ROUTE_INFO is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=m +# CONFIG_IPV6_MIP6 is not set +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +# CONFIG_IPV6_GRE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +# CONFIG_NETFILTER_NETLINK_ACCT is not set +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_ZONES is not set +CONFIG_NF_CONNTRACK_PROCFS=y +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +# CONFIG_NF_CONNTRACK_SNMP is not set +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +# CONFIG_NETFILTER_NETLINK_QUEUE_CT is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NETFILTER_XTABLES=m + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_BPF is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +CONFIG_NETFILTER_XT_MATCH_POLICY=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +CONFIG_NETFILTER_XT_MATCH_REALM=m +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +CONFIG_NETFILTER_XT_MATCH_U32=m +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +# CONFIG_IP_NF_MATCH_RPFILTER is not set +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT_IPV4=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +# CONFIG_NF_DEFRAG_IPV6 is not set +# CONFIG_NF_CONNTRACK_IPV6 is not set +CONFIG_IP6_NF_IPTABLES=m +# CONFIG_IP6_NF_MATCH_AH is not set +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RPFILTER is not set +CONFIG_IP6_NF_MATCH_RT=m +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_FILTER=m +# CONFIG_IP6_NF_TARGET_REJECT is not set +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +# CONFIG_IP6_NF_SECURITY is not set +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +CONFIG_IP_SCTP=m +# CONFIG_NET_SCTPPROBE is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_COOKIE_HMAC_SHA1 is not set +# CONFIG_RDS is not set +CONFIG_TIPC=m +CONFIG_TIPC_PORTS=8191 +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_BRIDGE_VLAN_FILTERING is not set +CONFIG_HAVE_NET_DSA=y +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_VLAN_8021Q_MVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +# CONFIG_NET_SCH_MULTIQ is not set +CONFIG_NET_SCH_RED=m +# CONFIG_NET_SCH_SFB is not set +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_QFQ is not set +CONFIG_NET_SCH_CODEL=m +# CONFIG_NET_SCH_FQ_CODEL is not set +CONFIG_NET_SCH_FQ=m +CONFIG_NET_SCH_INGRESS=m +# CONFIG_NET_SCH_PLUG is not set + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=y +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +CONFIG_NET_CLS_U32=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CLS_U32_MARK is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_CLS_CGROUP=y +# CONFIG_NET_EMATCH is not set +CONFIG_NET_CLS_ACT=y +# CONFIG_NET_ACT_POLICE is not set +# CONFIG_NET_ACT_GACT is not set +CONFIG_NET_ACT_MIRRED=m +# CONFIG_NET_ACT_IPT is not set +# CONFIG_NET_ACT_NAT is not set +# CONFIG_NET_ACT_PEDIT is not set +# CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set +# CONFIG_NET_ACT_CSUM is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +# CONFIG_VSOCKETS is not set +# CONFIG_NETLINK_MMAP is not set +# CONFIG_NETLINK_DIAG is not set +# CONFIG_NET_MPLS_GSO is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_NETPRIO_CGROUP is not set +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +# CONFIG_CFG80211_WEXT is not set +# CONFIG_LIB80211 is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_MESSAGE_TRACING is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set +CONFIG_HAVE_BPF_JIT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FW_LOADER_USER_HELPER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_DMA_SHARED_BUFFER=y + +# +# Bus devices +# +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +# CONFIG_MTD is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_AX88796 is not set +# CONFIG_PARPORT_1284 is not set +CONFIG_PNP=y +CONFIG_PNP_DEBUG_MESSAGES=y + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_FD=m +# CONFIG_PARIDE is not set +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_DRBD is not set +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_NVME is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_VIRTIO_BLK=y +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_BLK_DEV_RSXX is not set + +# +# Misc devices +# +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_DUMMY_IRQ is not set +# CONFIG_IBM_ASM is not set +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ATMEL_SSC is not set +CONFIG_ENCLOSURE_SERVICES=m +# CONFIG_HP_ILO is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_BMP085_I2C is not set +# CONFIG_BMP085_SPI is not set +# CONFIG_PCH_PHUB is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_LATTICE_ECP3_CONFIG is not set +# CONFIG_SRAM is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +CONFIG_EEPROM_LEGACY=m +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_CB710_CORE is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set +# CONFIG_INTEL_MEI is not set +# CONFIG_INTEL_MEI_ME is not set +# CONFIG_VMWARE_VMCI is not set +CONFIG_HAVE_IDE=y +CONFIG_IDE=y + +# +# Please see Documentation/ide/ide.txt for help/info on IDE drives +# +CONFIG_IDE_XFER_MODE=y +CONFIG_IDE_ATAPI=y +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_IDE_GD=y +CONFIG_IDE_GD_ATA=y +# CONFIG_IDE_GD_ATAPI is not set +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEACPI is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_PROC_FS=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +# CONFIG_BLK_DEV_PLATFORM is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_IDEPNP is not set +CONFIG_BLK_DEV_IDEDMA_SFF=y + +# +# PCI IDE chipsets support +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_PCIBUS_ORDER=y +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_ATIIXP is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_IT8172 is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set +CONFIG_BLK_DEV_IDEDMA=y + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_ENCLOSURE is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_CXGB3_ISCSI is not set +# CONFIG_SCSI_CXGB4_ISCSI is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_SCSI_BNX2X_FCOE is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_MVUMI is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_ESAS2R is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_MPT3SAS is not set +# CONFIG_SCSI_UFSHCD is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_VMWARE_PVSCSI is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set +# CONFIG_FCOE_FNIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_ISCI is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set +# CONFIG_SCSI_VIRTIO is not set +# CONFIG_SCSI_CHELSIO_FCOE is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_ACPI=y +# CONFIG_SATA_ZPODD is not set +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=m +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_ACARD_AHCI is not set +# CONFIG_SATA_SIL24 is not set +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_SX4 is not set +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +CONFIG_ATA_PIIX=y +# CONFIG_SATA_HIGHBANK is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_RCAR is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set + +# +# PATA SFF controllers with BMDMA +# +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CS5536 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SCH=y +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set + +# +# PIO-only SFF controllers +# +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_RZ1000 is not set + +# +# Generic fallback / legacy drivers +# +# CONFIG_PATA_ACPI is not set +CONFIG_ATA_GENERIC=y +# CONFIG_PATA_LEGACY is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID10=y +# CONFIG_MD_RAID456 is not set +CONFIG_MD_MULTIPATH=y +CONFIG_MD_FAULTY=y +# CONFIG_BCACHE is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=y +CONFIG_DM_SNAPSHOT=y +# CONFIG_DM_THIN_PROVISIONING is not set +# CONFIG_DM_CACHE is not set +CONFIG_DM_MIRROR=y +# CONFIG_DM_RAID is not set +# CONFIG_DM_LOG_USERSPACE is not set +CONFIG_DM_ZERO=y +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_VERITY is not set +# CONFIG_DM_SWITCH is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +CONFIG_I2O=m +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +# CONFIG_I2O_BUS is not set +CONFIG_I2O_BLOCK=m +CONFIG_I2O_SCSI=m +CONFIG_I2O_PROC=m +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +CONFIG_MII=y +CONFIG_NET_CORE=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +# CONFIG_EQUALIZER is not set +# CONFIG_NET_FC is not set +# CONFIG_IFB is not set +# CONFIG_NET_TEAM is not set +# CONFIG_MACVLAN is not set +# CONFIG_VXLAN is not set +CONFIG_NETCONSOLE=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_TUN=m +# CONFIG_VETH is not set +CONFIG_VIRTIO_NET=y +# CONFIG_NLMON is not set +# CONFIG_ARCNET is not set + +# +# CAIF transport drivers +# +# CONFIG_VHOST_NET is not set + +# +# Distributed Switch Architecture drivers +# +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6060 is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +# CONFIG_NET_DSA_MV88E6131 is not set +# CONFIG_NET_DSA_MV88E6123_61_65 is not set +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_3COM=y +# CONFIG_VORTEX is not set +# CONFIG_TYPHOON is not set +CONFIG_NET_VENDOR_ADAPTEC=y +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_NET_VENDOR_ALTEON=y +# CONFIG_ACENIC is not set +CONFIG_NET_VENDOR_AMD=y +# CONFIG_AMD8111_ETH is not set +CONFIG_PCNET32=y +CONFIG_NET_VENDOR_ARC=y +CONFIG_NET_VENDOR_ATHEROS=y +CONFIG_ATL2=m +# CONFIG_ATL1 is not set +CONFIG_ATL1E=m +# CONFIG_ATL1C is not set +# CONFIG_ALX is not set +CONFIG_NET_CADENCE=y +# CONFIG_ARM_AT91_ETHER is not set +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +CONFIG_TIGON3=y +# CONFIG_BNX2X is not set +CONFIG_NET_VENDOR_BROCADE=y +# CONFIG_BNA is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +CONFIG_NET_VENDOR_CISCO=y +# CONFIG_ENIC is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_DEC=y +# CONFIG_NET_TULIP is not set +CONFIG_NET_VENDOR_DLINK=y +# CONFIG_DL2K is not set +# CONFIG_SUNDANCE is not set +CONFIG_NET_VENDOR_EMULEX=y +# CONFIG_BE2NET is not set +CONFIG_NET_VENDOR_EXAR=y +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +CONFIG_NET_VENDOR_HP=y +# CONFIG_HP100 is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_E100=y +CONFIG_E1000=m +CONFIG_E1000E=m +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +# CONFIG_I40E is not set +CONFIG_NET_VENDOR_I825XX=y +# CONFIG_IP1000 is not set +# CONFIG_JME is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_NET_VENDOR_MELLANOX=y +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_MLX5_CORE is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +CONFIG_NET_VENDOR_MYRI=y +# CONFIG_MYRI10GE is not set +# CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NATSEMI=y +# CONFIG_NATSEMI is not set +# CONFIG_NS83820 is not set +CONFIG_NET_VENDOR_8390=y +# CONFIG_NE2K_PCI is not set +CONFIG_NET_VENDOR_NVIDIA=y +# CONFIG_FORCEDETH is not set +CONFIG_NET_VENDOR_OKI=y +# CONFIG_PCH_GBE is not set +# CONFIG_ETHOC is not set +CONFIG_NET_PACKET_ENGINE=y +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_NET_VENDOR_QLOGIC=y +# CONFIG_QLA3XXX is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_NETXEN_NIC is not set +CONFIG_NET_VENDOR_REALTEK=y +# CONFIG_ATP is not set +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_R8169=y +# CONFIG_SH_ETH is not set +CONFIG_NET_VENDOR_RDC=y +# CONFIG_R6040 is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SILAN=y +# CONFIG_SC92031 is not set +CONFIG_NET_VENDOR_SIS=y +# CONFIG_SIS900 is not set +# CONFIG_SIS190 is not set +# CONFIG_SFC is not set +CONFIG_NET_VENDOR_SMSC=y +# CONFIG_EPIC100 is not set +# CONFIG_SMSC911X is not set +# CONFIG_SMSC9420 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_SUN=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NIU is not set +CONFIG_NET_VENDOR_TEHUTI=y +# CONFIG_TEHUTI is not set +CONFIG_NET_VENDOR_TI=y +# CONFIG_TLAN is not set +CONFIG_NET_VENDOR_VIA=y +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_NET_SB1000 is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AT803X_PHY is not set +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM87XX_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MICREL_KS8995MA is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +# CONFIG_PPP_MPPE is not set +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLIP=m +CONFIG_SLHC=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_RTL8152 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_IPHETH is not set +CONFIG_WLAN=y +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_AIRO is not set +# CONFIG_ATMEL is not set +# CONFIG_AT76C50X_USB is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +# CONFIG_RTL8180 is not set +# CONFIG_RTL8187 is not set +# CONFIG_ADM8211 is not set +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_MWL8K is not set +CONFIG_ATH_COMMON=m +CONFIG_ATH_CARDS=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +# CONFIG_ATH5K_TRACER is not set +CONFIG_ATH5K_PCI=y +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +# CONFIG_ATH9K_AHB is not set +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_LEGACY_RATE_CONTROL is not set +CONFIG_ATH9K_RFKILL=y +# CONFIG_ATH9K_HTC is not set +# CONFIG_CARL9170 is not set +# CONFIG_ATH6KL is not set +# CONFIG_AR5523 is not set +# CONFIG_WIL6210 is not set +# CONFIG_ATH10K is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BRCMUTIL=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +# CONFIG_HOSTAP is not set +# CONFIG_IPW2100 is not set +# CONFIG_IWLWIFI is not set +# CONFIG_IWL4965 is not set +# CONFIG_IWL3945 is not set +# CONFIG_LIBERTAS is not set +# CONFIG_P54_COMMON is not set +CONFIG_RT2X00=m +# CONFIG_RT2400PCI is not set +# CONFIG_RT2500PCI is not set +# CONFIG_RT61PCI is not set +CONFIG_RT2800PCI=m +CONFIG_RT2800PCI_RT33XX=y +CONFIG_RT2800PCI_RT35XX=y +CONFIG_RT2800PCI_RT53XX=y +CONFIG_RT2800PCI_RT3290=y +# CONFIG_RT2500USB is not set +# CONFIG_RT73USB is not set +# CONFIG_RT2800USB is not set +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_MMIO=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RTL_CARDS=m +# CONFIG_RTL8192CE is not set +# CONFIG_RTL8192SE is not set +# CONFIG_RTL8192DE is not set +# CONFIG_RTL8723AE is not set +# CONFIG_RTL8188EE is not set +# CONFIG_RTL8192CU is not set +# CONFIG_WL_TI is not set +# CONFIG_ZD1211RW is not set +# CONFIG_MWIFIEX is not set +# CONFIG_CW1200 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_VMXNET3 is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set +# CONFIG_INPUT_MATRIXKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_CYPRESS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_CYAPA is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_GPIO is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_MOUSE_SYNAPTICS_USB is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TABLET=y +# CONFIG_TABLET_USB_ACECAD is not set +# CONFIG_TABLET_USB_AIPTEK is not set +# CONFIG_TABLET_USB_GTCO is not set +# CONFIG_TABLET_USB_HANWANG is not set +# CONFIG_TABLET_USB_KBTAB is not set +CONFIG_TABLET_USB_WACOM=y +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_SERIO_ARC_PS2 is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_DW is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_KGDB_NMI is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_MFD_HSU is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_CONSOLE_POLL=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_PCH_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_ST_ASC is not set +# CONFIG_TTY_PRINTK is not set +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +CONFIG_HVC_DRIVER=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_SI is not set +# CONFIG_IPMI_WATCHDOG is not set +# CONFIG_IPMI_POWEROFF is not set +CONFIG_HW_RANDOM=m +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_VIA=m +# CONFIG_HW_RANDOM_VIRTIO is not set +CONFIG_HW_RANDOM_TPM=m +CONFIG_NVRAM=m +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_MWAVE is not set +# CONFIG_RAW_DRIVER is not set +CONFIG_HPET=y +CONFIG_HPET_MMAP=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_TCG_TPM=y +# CONFIG_TCG_TIS is not set +# CONFIG_TCG_TIS_I2C_INFINEON is not set +# CONFIG_TCG_NSC is not set +# CONFIG_TCG_ATMEL is not set +# CONFIG_TCG_INFINEON is not set +# CONFIG_TCG_ST33_I2C is not set +# CONFIG_TELCLOCK is not set +CONFIG_DEVPORT=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_MUX is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +CONFIG_I2C_I801=y +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_ISMT is not set +CONFIG_I2C_PIIX4=m +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# ACPI drivers +# +# CONFIG_I2C_SCMI is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EG20T is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_BUTTERFLY is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_LM70_LLP is not set +# CONFIG_SPI_FSL_DSPI is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_SC18IS602 is not set +# CONFIG_SPI_TOPCLIFF_PCH is not set +# CONFIG_SPI_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=m +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_PARPORT is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +# CONFIG_PTP_1588_CLOCK_PCH is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_ACPI=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC=m + +# +# Memory mapped GPIO drivers: +# +CONFIG_GPIO_GENERIC_PLATFORM=m +# CONFIG_GPIO_IT8761E is not set +# CONFIG_GPIO_F7188X is not set +# CONFIG_GPIO_TS5500 is not set +# CONFIG_GPIO_SCH is not set +# CONFIG_GPIO_ICH is not set +# CONFIG_GPIO_VX855 is not set +# CONFIG_GPIO_LYNXPOINT is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_AMD8111 is not set +# CONFIG_GPIO_LANGWELL is not set +# CONFIG_GPIO_PCH is not set +# CONFIG_GPIO_ML_IOH is not set +# CONFIG_GPIO_RDC321X is not set + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# LPC GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# + +# +# USB GPIO expanders: +# +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_POWER_RESET is not set +# CONFIG_POWER_AVS is not set +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ABITUGURU3 is not set +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADT7310 is not set +# CONFIG_SENSORS_ADT7410 is not set +# CONFIG_SENSORS_ADT7411 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7475 is not set +# CONFIG_SENSORS_ASC7621 is not set +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_K10TEMP=m +CONFIG_SENSORS_FAM15H_POWER=m +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS620 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_FSCHMD is not set +# CONFIG_SENSORS_G760A is not set +# CONFIG_SENSORS_G762 is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_GPIO_FAN is not set +# CONFIG_SENSORS_HIH6130 is not set +# CONFIG_SENSORS_HTU21 is not set +# CONFIG_SENSORS_CORETEMP is not set +# CONFIG_SENSORS_IBMAEM is not set +# CONFIG_SENSORS_IBMPEX is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_LINEAGE is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM73 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_LTC4151 is not set +# CONFIG_SENSORS_LTC4215 is not set +# CONFIG_SENSORS_LTC4245 is not set +# CONFIG_SENSORS_LTC4261 is not set +# CONFIG_SENSORS_LM95234 is not set +# CONFIG_SENSORS_LM95241 is not set +# CONFIG_SENSORS_LM95245 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16065 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX1668 is not set +# CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX6639 is not set +# CONFIG_SENSORS_MAX6642 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MCP3021 is not set +# CONFIG_SENSORS_NCT6775 is not set +# CONFIG_SENSORS_NTC_THERMISTOR is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_PMBUS is not set +# CONFIG_SENSORS_SHT15 is not set +# CONFIG_SENSORS_SHT21 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMM665 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_EMC1403 is not set +# CONFIG_SENSORS_EMC2103 is not set +# CONFIG_SENSORS_EMC6W201 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SCH56XX_COMMON is not set +# CONFIG_SENSORS_SCH5627 is not set +# CONFIG_SENSORS_SCH5636 is not set +# CONFIG_SENSORS_ADS1015 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADS7871 is not set +# CONFIG_SENSORS_AMC6821 is not set +# CONFIG_SENSORS_INA209 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_VIA_CPUTEMP is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83795 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_APPLESMC is not set + +# +# ACPI drivers +# +CONFIG_SENSORS_ACPI_POWER=m +# CONFIG_SENSORS_ATK0110 is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_USER_SPACE=y +# CONFIG_CPU_THERMAL is not set +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_INTEL_POWERCLAMP is not set +CONFIG_X86_PKG_TEMP_THERMAL=m + +# +# Texas Instruments thermal drivers +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM1535_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_F71808E_WDT is not set +# CONFIG_SP5100_TCO is not set +# CONFIG_SC520_WDT is not set +# CONFIG_SBC_FITPC2_WATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_IBMASR is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_IE6XX_WDT is not set +# CONFIG_ITCO_WDT is not set +# CONFIG_IT8712F_WDT is not set +# CONFIG_IT87_WDT is not set +# CONFIG_HP_WATCHDOG is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_PC87413_WDT is not set +# CONFIG_NV_TCO is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SBC8360_WDT is not set +# CONFIG_CPU5_WDT is not set +# CONFIG_SMSC_SCH311X_WDT is not set +# CONFIG_SMSC37B787_WDT is not set +# CONFIG_VIA_WDT is not set +# CONFIG_W83627HF_WDT is not set +# CONFIG_W83697HF_WDT is not set +# CONFIG_W83697UG_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_W83977F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_SBC_EPX_C3_WATCHDOG is not set +# CONFIG_MEN_A21_WDT is not set + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_CS5535 is not set +# CONFIG_MFD_AS3711 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_CROS_EC is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_LPC_ICH is not set +# CONFIG_LPC_SCH is not set +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RTSX_PCI is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_SYSCON is not set +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TIMBERDALE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_VX855 is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_RC_SUPPORT is not set +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2=m +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_VMALLOC=m +# CONFIG_VIDEO_V4L2_INT_DEVICE is not set +# CONFIG_TTPCI_EEPROM is not set + +# +# Media drivers +# +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set +# CONFIG_USB_GL860 is not set +# CONFIG_USB_GSPCA_BENQ is not set +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_CPIA1 is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_JEILINJ is not set +# CONFIG_USB_GSPCA_JL2005BCD is not set +# CONFIG_USB_GSPCA_KINECT is not set +# CONFIG_USB_GSPCA_KONICA is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_MR97310A is not set +# CONFIG_USB_GSPCA_NW80X is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_OV534 is not set +# CONFIG_USB_GSPCA_OV534_9 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7302 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SE401 is not set +# CONFIG_USB_GSPCA_SN9C2028 is not set +# CONFIG_USB_GSPCA_SN9C20X is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_SPCA1528 is not set +# CONFIG_USB_GSPCA_SQ905 is not set +# CONFIG_USB_GSPCA_SQ905C is not set +# CONFIG_USB_GSPCA_SQ930X is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_STK1135 is not set +# CONFIG_USB_GSPCA_STV0680 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TOPRO is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_VICAM is not set +# CONFIG_USB_GSPCA_XIRLINK_CIT is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_VIDEO_USBTV is not set + +# +# Webcam, TV (analog/digital) USB devices +# +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_MEDIA_PCI_SUPPORT is not set +# CONFIG_V4L_PLATFORM_DRIVERS is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_V4L_TEST_DRIVERS is not set + +# +# Supported MMC/SDIO adapters +# +# CONFIG_MEDIA_PARPORT_SUPPORT is not set +# CONFIG_CYPRESS_FIRMWARE is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, frontends) +# +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y + +# +# Audio decoders, processors and mixers +# + +# +# RDS decoders +# + +# +# Video decoders +# + +# +# Video and audio decoders +# + +# +# Video encoders +# + +# +# Camera sensor devices +# + +# +# Flash devices +# + +# +# Video improvement chips +# + +# +# Miscelaneous helper chips +# + +# +# Sensors used on soc_camera driver +# + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set + +# +# Graphics support +# +CONFIG_AGP=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=y +# CONFIG_AGP_SIS is not set +# CONFIG_AGP_VIA is not set +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_VGA_SWITCHEROO=y +CONFIG_DRM=m +CONFIG_DRM_KMS_HELPER=m +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_TTM=m + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=m +CONFIG_DRM_RADEON_UMS=y +# CONFIG_DRM_NOUVEAU is not set +CONFIG_DRM_I915=m +CONFIG_DRM_I915_KMS=y +# CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT is not set +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set +# CONFIG_DRM_VMWGFX is not set +# CONFIG_DRM_GMA500 is not set +# CONFIG_DRM_UDL is not set +# CONFIG_DRM_AST is not set +# CONFIG_DRM_MGAG200 is not set +# CONFIG_DRM_CIRRUS_QEMU is not set +# CONFIG_DRM_QXL is not set +CONFIG_VGASTATE=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_HDMI=y +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_DDC=m +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=m +# CONFIG_FB_UVESA is not set +# CONFIG_FB_VESA is not set +CONFIG_FB_EFI=y +# CONFIG_FB_N411 is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_MATROX is not set +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIA is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_GOLDFISH is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_FB_SIMPLE is not set +# CONFIG_EXYNOS_VIDEO is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_L4F00242T03 is not set +# CONFIG_LCD_LMS283GF05 is not set +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_ILI922X is not set +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +CONFIG_LCD_PLATFORM=m +# CONFIG_LCD_S6E63M0 is not set +# CONFIG_LCD_LD9040 is not set +# CONFIG_LCD_AMS369FG06 is not set +# CONFIG_LCD_LMS501KF03 is not set +# CONFIG_LCD_HX8357 is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y +# CONFIG_BACKLIGHT_APPLE is not set +# CONFIG_BACKLIGHT_SAHARA is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +# CONFIG_BACKLIGHT_LM3630 is not set +# CONFIG_BACKLIGHT_LM3639 is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_BACKLIGHT_GPIO is not set +# CONFIG_BACKLIGHT_LV5207LP is not set +# CONFIG_BACKLIGHT_BD6107 is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=y +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_KCTL_JACK=y +CONFIG_SND_DMA_SGBUF=y +CONFIG_SND_RAWMIDI_SEQ=m +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +CONFIG_SND_DRIVERS=y +CONFIG_SND_PCSP=m +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_ALOOP is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_MTS64 is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_PORTMAN2X4 is not set +CONFIG_SND_PCI=y +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ASIHPI is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5530 is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_CTXFI is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_INDIGOIOX is not set +# CONFIG_SND_INDIGODJX is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +CONFIG_SND_HDA_INTEL=y +CONFIG_SND_HDA_PREALLOC_SIZE=64 +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_RECONFIG=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INPUT_BEEP_MODE=1 +CONFIG_SND_HDA_INPUT_JACK=y +CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_CODEC_HDMI=y +CONFIG_SND_HDA_I915=y +CONFIG_SND_HDA_CODEC_CIRRUS=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_CA0110=y +CONFIG_SND_HDA_CODEC_CA0132=y +# CONFIG_SND_HDA_CODEC_CA0132_DSP is not set +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_GENERIC=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_LOLA is not set +# CONFIG_SND_LX6464ES is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +CONFIG_SND_SPI=y +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_USX2Y is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_US122L is not set +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_USB_HIFACE is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set + +# +# HID support +# +CONFIG_HID=y +# CONFIG_HID_BATTERY_STRENGTH is not set +# CONFIG_HIDRAW is not set +# CONFIG_UHID is not set +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_APPLEIR is not set +# CONFIG_HID_AUREAL is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_ELO is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_HUION is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_ICADE is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LENOVO_TPKBD is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SPEEDLINK is not set +# CONFIG_HID_STEELSERIES is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TIVO is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THINGM is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_WIIMOTE is not set +# CONFIG_HID_XINMO is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +# CONFIG_HID_SENSOR_HUB is not set + +# +# USB HID support +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +# CONFIG_I2C_HID is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_FUSBH200_HCD is not set +# CONFIG_USB_FOTG210_HCD is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PCI=m +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_UHCI_HCD=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_CHIPIDEA is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_SIMPLE is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_CH341 is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=y +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_IUU is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=y +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_XSENS_MT is not set +# CONFIG_USB_SERIAL_WISHBONE is not set +# CONFIG_USB_SERIAL_ZTE is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_QT2 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_EZUSB_FX2=y +# CONFIG_USB_HSIC_USB3503 is not set + +# +# USB Physical Layer drivers +# +# CONFIG_USB_PHY is not set +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_AM335X_PHY_USB is not set +# CONFIG_SAMSUNG_USB2PHY is not set +# CONFIG_SAMSUNG_USB3PHY is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_RCAR_PHY is not set +# CONFIG_USB_GADGET is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +# CONFIG_MMC_CLKGATE is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PCI=y +# CONFIG_MMC_RICOH_MMC is not set +# CONFIG_MMC_SDHCI_ACPI is not set +CONFIG_MMC_SDHCI_PLTFM=m +# CONFIG_MMC_WBSD is not set +# CONFIG_MMC_TIFM_SD is not set +CONFIG_MMC_SPI=m +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_LM3642 is not set +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_GPIO is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_LP5562 is not set +# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_CLEVO_MAIL is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA963X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_INTEL_SS4200 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_LM355x is not set +# CONFIG_LEDS_OT200 is not set +# CONFIG_LEDS_BLINKM is not set + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_TIMER is not set +# CONFIG_LEDS_TRIGGER_ONESHOT is not set +# CONFIG_LEDS_TRIGGER_IDE_DISK is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_CPU is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set +# CONFIG_LEDS_TRIGGER_CAMERA is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC=y +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_DECODE_MCE=y +CONFIG_EDAC_MCE_INJ=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_AMD64=m +# CONFIG_EDAC_AMD64_ERROR_INJECTION is not set +# CONFIG_EDAC_E752X is not set +# CONFIG_EDAC_I82975X is not set +# CONFIG_EDAC_I3000 is not set +# CONFIG_EDAC_I3200 is not set +# CONFIG_EDAC_X38 is not set +# CONFIG_EDAC_I5400 is not set +# CONFIG_EDAC_I7CORE is not set +# CONFIG_EDAC_I5000 is not set +# CONFIG_EDAC_I5100 is not set +# CONFIG_EDAC_I7300 is not set +# CONFIG_EDAC_SBRIDGE is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_PCF8523 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set +# CONFIG_RTC_DRV_RX4581 is not set + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_DS2404 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_MOXART is not set + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +# CONFIG_DMADEVICES is not set +CONFIG_AUXDISPLAY=y +# CONFIG_KS0108 is not set +# CONFIG_UIO is not set +# CONFIG_VFIO is not set +# CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRTIO=y + +# +# Virtio drivers +# +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_MMIO=y +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set + +# +# Microsoft Hyper-V guest support +# +# CONFIG_STAGING is not set +CONFIG_X86_PLATFORM_DEVICES=y +# CONFIG_ACERHDF is not set +# CONFIG_ASUS_LAPTOP is not set +# CONFIG_CHROMEOS_LAPTOP is not set +# CONFIG_FUJITSU_LAPTOP is not set +# CONFIG_FUJITSU_TABLET is not set +# CONFIG_AMILO_RFKILL is not set +# CONFIG_HP_ACCEL is not set +# CONFIG_MSI_LAPTOP is not set +# CONFIG_PANASONIC_LAPTOP is not set +# CONFIG_COMPAL_LAPTOP is not set +# CONFIG_SONY_LAPTOP is not set +# CONFIG_IDEAPAD_LAPTOP is not set +# CONFIG_THINKPAD_ACPI is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_INTEL_MENLOW is not set +# CONFIG_EEEPC_LAPTOP is not set +# CONFIG_ACPI_WMI is not set +# CONFIG_TOPSTAR_LAPTOP is not set +# CONFIG_TOSHIBA_BT_RFKILL is not set +# CONFIG_ACPI_CMPC is not set +# CONFIG_INTEL_IPS is not set +# CONFIG_IBM_RTL is not set +# CONFIG_XO15_EBOOK is not set +# CONFIG_SAMSUNG_LAPTOP is not set +# CONFIG_INTEL_OAKTRAIL is not set +# CONFIG_SAMSUNG_Q10 is not set +# CONFIG_APPLE_GMUX is not set +# CONFIG_INTEL_RST is not set +# CONFIG_INTEL_SMARTCONNECT is not set +# CONFIG_PVPANIC is not set + +# +# Hardware Spinlock drivers +# +CONFIG_CLKEVT_I8253=y +CONFIG_I8253_LOCK=y +CONFIG_CLKBLD_I8253=y +# CONFIG_MAILBOX is not set +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y +CONFIG_AMD_IOMMU=y +CONFIG_AMD_IOMMU_STATS=y +CONFIG_AMD_IOMMU_V2=m +CONFIG_DMAR_TABLE=y +# CONFIG_INTEL_IOMMU is not set +CONFIG_IRQ_REMAP=y + +# +# Remoteproc drivers +# +# CONFIG_STE_MODEM_RPROC is not set + +# +# Rpmsg drivers +# +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y + +# +# DEVFREQ Drivers +# +# CONFIG_EXTCON is not set +CONFIG_MEMORY=y +# CONFIG_IIO is not set +# CONFIG_NTB is not set +# CONFIG_VME_BUS is not set +# CONFIG_PWM is not set +# CONFIG_IPACK_BUS is not set +# CONFIG_RESET_CONTROLLER is not set +# CONFIG_FMC is not set + +# +# Firmware Drivers +# +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_FIRMWARE_MEMMAP=y +# CONFIG_DELL_RBU is not set +# CONFIG_DCDBAS is not set +CONFIG_DMIID=y +CONFIG_DMI_SYSFS=m +# CONFIG_ISCSI_IBFT_FIND is not set +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_VARS=y +CONFIG_EFI_VARS_PSTORE=y +# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_DEFAULTS_TO_ORDERED=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +# CONFIG_REISERFS_FS_SECURITY is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_ASSERT is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_VMCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TMPFS_XATTR is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +CONFIG_MINIX_FS=m +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_PSTORE=y +# CONFIG_PSTORE_CONSOLE is not set +# CONFIG_PSTORE_FTRACE is not set +# CONFIG_PSTORE_RAM is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_F2FS_FS is not set +# CONFIG_EFIVAR_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_SWAP is not set +# CONFIG_NFS_V4_1 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_ACL is not set +CONFIG_CIFS_DEBUG=y +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_SMB2 is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y + +# +# printk and dmesg options +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_DYNAMIC_DEBUG is not set + +# +# Compile-time checks and compiler options +# +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y + +# +# Memory Debugging +# +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_HAVE_DEBUG_STACKOVERFLOW=y +# CONFIG_DEBUG_STACKOVERFLOW is not set +CONFIG_HAVE_ARCH_KMEMCHECK=y +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +# CONFIG_LOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_PREEMPT=y + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set + +# +# RCU Debugging +# +# CONFIG_PROVE_RCU_DELAY is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_CPU_STALL_VERBOSE=y +# CONFIG_RCU_CPU_STALL_INFO is not set +# CONFIG_RCU_TRACE is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_LATENCYTOP=y +CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_FENTRY=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +CONFIG_FTRACE_SYSCALLS=y +# CONFIG_TRACER_SNAPSHOT is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +# CONFIG_STACK_TRACER is not set +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_KPROBE_EVENT=y +CONFIG_UPROBE_EVENT=y +CONFIG_PROBE_EVENTS=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_DYNAMIC_FTRACE_WITH_REGS=y +# CONFIG_FUNCTION_PROFILER is not set +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_MMIOTRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_RING_BUFFER_STARTUP_TEST is not set + +# +# Runtime Testing +# +# CONFIG_LKDTM is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_KPROBES_SANITY_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_RBTREE_TEST is not set +# CONFIG_INTERVAL_TREE_TEST is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_TEST_STRING_HELPERS is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KGDB_LOW_LEVEL_TRAP=y +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y +CONFIG_KDB_CONTINUE_CATASTROPHIC=0 +# CONFIG_STRICT_DEVMEM is not set +CONFIG_X86_VERBOSE_BOOTUP=y +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +# CONFIG_X86_PTDUMP is not set +CONFIG_DEBUG_RODATA=y +CONFIG_DEBUG_RODATA_TEST=y +# CONFIG_DEBUG_SET_MODULE_RONX is not set +# CONFIG_DEBUG_NX_TEST is not set +CONFIG_DOUBLEFAULT=y +# CONFIG_DEBUG_TLBFLUSH is not set +# CONFIG_IOMMU_DEBUG is not set +# CONFIG_IOMMU_STRESS is not set +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +# CONFIG_X86_DECODER_SELFTEST is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=0 +# CONFIG_DEBUG_BOOT_PARAMS is not set +# CONFIG_CPA_DEBUG is not set +# CONFIG_OPTIMIZE_INLINING is not set +# CONFIG_DEBUG_NMI_SELFTEST is not set +# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_TRUSTED_KEYS is not set +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +# CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SECURITY_TOMOYO is not set +# CONFIG_SECURITY_APPARMOR is not set +# CONFIG_SECURITY_YAMA is not set +# CONFIG_IMA is not set +# CONFIG_EVM is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_XOR_BLOCKS=y +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_TEST=m + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +CONFIG_CRYPTO_SEQIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=m +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=m +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32C_INTEL is not set +# CONFIG_CRYPTO_CRC32 is not set +# CONFIG_CRYPTO_CRC32_PCLMUL is not set +CONFIG_CRYPTO_CRCT10DIF=y +# CONFIG_CRYPTO_CRCT10DIF_PCLMUL is not set +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA1_SSSE3 is not set +# CONFIG_CRYPTO_SHA256_SSSE3 is not set +# CONFIG_CRYPTO_SHA512_SSSE3 is not set +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_WP512=m +# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_AES_X86_64 is not set +# CONFIG_CRYPTO_AES_NI_INTEL is not set +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_BLOWFISH_COMMON=m +# CONFIG_CRYPTO_BLOWFISH_X86_64 is not set +CONFIG_CRYPTO_CAMELLIA=m +# CONFIG_CRYPTO_CAMELLIA_X86_64 is not set +# CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64 is not set +# CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 is not set +CONFIG_CRYPTO_CAST_COMMON=m +CONFIG_CRYPTO_CAST5=m +# CONFIG_CRYPTO_CAST5_AVX_X86_64 is not set +CONFIG_CRYPTO_CAST6=m +# CONFIG_CRYPTO_CAST6_AVX_X86_64 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +CONFIG_CRYPTO_KHAZAD=m +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SALSA20_X86_64 is not set +# CONFIG_CRYPTO_SEED is not set +CONFIG_CRYPTO_SERPENT=m +# CONFIG_CRYPTO_SERPENT_SSE2_X86_64 is not set +# CONFIG_CRYPTO_SERPENT_AVX_X86_64 is not set +# CONFIG_CRYPTO_SERPENT_AVX2_X86_64 is not set +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +# CONFIG_CRYPTO_TWOFISH_X86_64 is not set +# CONFIG_CRYPTO_TWOFISH_X86_64_3WAY is not set +# CONFIG_CRYPTO_TWOFISH_AVX_X86_64 is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_PADLOCK is not set +# CONFIG_ASYMMETRIC_KEY_TYPE is not set +CONFIG_HAVE_KVM=y +CONFIG_VIRTUALIZATION=y +# CONFIG_KVM is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=y +CONFIG_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_PERCPU_RWSEM=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_CMPXCHG_LOCKREF=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +CONFIG_CRC7=m +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_AVERAGE=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +CONFIG_OID_REGISTRY=y +CONFIG_UCS2_STRING=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y diff --git a/meta-steppeeagle/recipes-kernel/linux/linux-yocto_3.12.bb b/meta-steppeeagle/recipes-kernel/linux/linux-yocto_3.12.bb new file mode 100644 index 00000000..519c4be9 --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/linux/linux-yocto_3.12.bb @@ -0,0 +1,71 @@ +DESCRIPTION = "Linux Kernel v3.12" +SECTION = "kernel" +LICENSE = "GPLv2" + +LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7" + +inherit kernel + +SRC_URI = "http://git.yoctoproject.org/cgit/cgit.cgi/linux-yocto-dev/snapshot/linux-yocto-dev-${PV}.tar.bz2;name=kernel \ + file://defconfig \ + file://0000-yocto-amd-drm-radeon-backport-support-from-kernel-version-3.12.10.patch \ + file://0001-yocto-amd-drm-radeon-add-vm_set_page-tracepoint.patch \ + file://0002-yocto-amd-drm-radeon-cleanup-flushing-on-CIK-v3.patch \ + file://0003-yocto-amd-drm-radeon-cleanup-DMA-HDP-flush-on-CIK-v2.patch \ + file://0004-yocto-amd-drm-radeon-allow-semaphore-emission-to-fail.patch \ + file://0005-yocto-amd-drm-radeon-improve-ring-debugfs-a-bit.patch \ + file://0006-yocto-amd-drm-radeon-report-the-real-offset-in-radeon_sa_bo_du.patch \ + file://0007-yocto-amd-drm-radeon-update-fence-values-in-before-reporting-t.patch \ + file://0008-yocto-amd-drm-radeon-cleanup-radeon_ttm-debugfs-handling.patch \ + file://0009-yocto-amd-drm-radeon-add-VRAM-debugfs-access-v3.patch \ + file://0010-yocto-amd-drm-radeon-add-GART-debugfs-access-v3.patch \ + file://0011-yocto-amd-drm-radeon-fix-VMID-use-tracking.patch \ + file://0012-yocto-amd-drm-radeon-add-missing-trace-point.patch \ + file://0013-yocto-amd-drm-radeon-add-semaphore-trace-point.patch \ + file://0014-yocto-amd-drm-radeon-add-VMID-allocation-trace-point.patch \ + file://0015-yocto-amd-drm-radeon-add-uvd-debugfs-support.patch \ + file://0016-yocto-amd-drm-radeon-add-radeon_vm_bo_update-trace-point.patch \ + file://0017-yocto-amd-drm-radeon-drop-CP-page-table-updates-cleanup-v2.patch \ + file://0018-yocto-amd-drm-radeon-add-large-PTE-support-for-NI-SI-and-CIK-v.patch \ + file://0019-yocto-amd-drm-radeon-add-proper-support-for-RADEON_VM_BLOCK_SI.patch \ + file://0020-yocto-amd-drm-radeon-WIP-add-copy-trace-point.patch \ + file://0021-yocto-amd-drm-radeon-cik-Return-backend-map-information-to-use.patch \ + file://0022-yocto-amd-drm-radeon-cik-Add-macrotile-mode-array-query.patch \ + file://0023-yocto-amd-drm-radeon-set-correct-number-of-banks-for-CIK-chips.patch \ + file://0024-yocto-amd-drm-radeon-don-t-power-gate-paused-UVD-streams.patch \ + file://0025-yocto-amd-drm-radeon-dpm-retain-user-selected-performance-leve.patch \ + file://0026-yocto-amd-drm-radeon-remove-generic-rptr-wptr-functions-v2.patch \ + file://0027-yocto-amd-drm-radeon-initial-VCE-support-v4.patch \ + file://0028-yocto-amd-drm-radeon-add-VCE-ring-query.patch \ + file://0029-yocto-amd-drm-radeon-add-VCE-version-parsing-and-checking.patch \ + file://0030-yocto-amd-drm-radeon-add-callback-for-setting-vce-clocks.patch \ + file://0031-yocto-amd-drm-radeon-dpm-move-platform-caps-fetching-to-a-sepa.patch \ + file://0032-yocto-amd-drm-radeon-dpm-fill-in-some-initial-vce-infrastructu.patch \ + file://0033-yocto-amd-drm-radeon-dpm-fetch-vce-states-from-the-vbios.patch \ + file://0034-yocto-amd-drm-radeon-fill-in-set_vce_clocks-for-CIK-asics.patch \ + file://0035-yocto-amd-drm-radeon-add-vce-dpm-support-for-CI.patch \ + file://0036-yocto-amd-drm-radeon-enable-vce-dpm-on-CI.patch \ + file://0037-yocto-amd-drm-radeon-add-vce-dpm-support-for-KV-KB.patch \ + file://0038-yocto-amd-drm-radeon-dpm-enable-dynamic-vce-state-switching-v2.patch \ + file://0039-yocto-amd-drm-radeon-dpm-properly-enable-disable-vce-when-vce-.patch \ + file://0040-yocto-amd-drm-radeon-add-vce-debugfs-support.patch \ + file://0041-yocto-amd-drm-radeon-add-support-for-vce-2.0-clock-gating.patch \ + file://0042-yocto-amd-drm-radeon-cik-enable-disable-vce-cg-when-encoding.patch \ + file://0043-yocto-amd-drm-radeon-fix-CP-semaphores-on-CIK.patch \ + file://0044-yocto-amd-drm-radeon-disable-dynamic-powering-vce.patch \ + file://0045-yocto-amd-drm-radeon-add-Mullins-chip-family.patch \ + file://0046-yocto-amd-drm-radeon-update-cik-init-for-Mullins.patch \ + file://0047-yocto-amd-drm-radeon-add-Mullins-UVD-support.patch \ + file://0048-yocto-amd-drm-radeon-add-Mullins-dpm-support.patch \ + file://0049-yocto-amd-drm-radeon-modesetting-updates-for-Mullins.patch \ + file://0050-yocto-amd-drm-radeon-add-pci-ids-for-Mullins.patch \ + file://0051-yocto-amd-drm-radeon-add-Mulins-VCE-support.patch \ + file://0052-yocto-amd-clear-exceptions-in-AMD-FXSAVE-workaround.patch \ + file://0053-yocto-amd-i2c-piix4-add-support-for-AMD-ML-and-CZ-SMBus-changes.patch \ + file://0054-yocto-amd-i2c-piix4-use-different-message-for-AMD-auxiliary-SMBus-controller.patch \ + file://0055-yocto-amd-change-acpi-enforce-resources-to-lax.patch" + +S = "${WORKDIR}/linux-yocto-dev-${PV}" + +SRC_URI[kernel.md5sum] = "3b58ba37133ace5e486cee3697a810be" +SRC_URI[kernel.sha256sum] = "b4e914b4682d92f691da22ce8f2c89bfcd710515c416164ce57de0c7eca7ab3c" diff --git a/meta-steppeeagle/recipes-kernel/wdt-load/amd-wdt-load_1.0.bb b/meta-steppeeagle/recipes-kernel/wdt-load/amd-wdt-load_1.0.bb new file mode 100644 index 00000000..b124e12c --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/wdt-load/amd-wdt-load_1.0.bb @@ -0,0 +1,18 @@ +DESCRIPTION = "Configuration file to pass module load parameters to AMD Watchdog driver" +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" + +SRC_URI = "file://modprobe.d/amd-wdt.conf" + +PR = "r0" +PV = "1.0" + +S = "${WORKDIR}" + +do_install() { + install -d ${D}/${sysconfdir}/modprobe.d/ + install -m 0644 modprobe.d/amd-wdt.conf ${D}${sysconfdir}/modprobe.d/ +} + +FILES_${PN} = "${sysconfdir}/modprobe.d" + diff --git a/meta-steppeeagle/recipes-kernel/wdt-load/files/modprobe.d/amd-wdt.conf b/meta-steppeeagle/recipes-kernel/wdt-load/files/modprobe.d/amd-wdt.conf new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/meta-steppeeagle/recipes-kernel/wdt-load/files/modprobe.d/amd-wdt.conf diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0001-gstomxvideodec-fix-multithreads-negotiation-problem-.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0001-gstomxvideodec-fix-multithreads-negotiation-problem-.patch new file mode 100644 index 00000000..28078995 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0001-gstomxvideodec-fix-multithreads-negotiation-problem-.patch @@ -0,0 +1,36 @@ +From c223d8863624a93cd969b421b302df5d74f7fbaf Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Thu, 7 Nov 2013 13:13:19 -0500 +Subject: [PATCH 01/11] gstomxvideodec: fix multithreads negotiation problem + v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +v2: update comment text + +Signed-off-by: Leo Liu <leo.liu@amd.com> +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideodec.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index bf44b3d..0d8801e 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -2675,6 +2675,11 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder, + if (!gst_omx_video_dec_negotiate (self)) + GST_LOG_OBJECT (self, "Negotiation failed, will get output format later"); + ++ /* Make sure other threads are done enabling it */ ++ if (gst_omx_port_wait_enabled (self->dec_out_port, ++ 1 * GST_SECOND) != OMX_ErrorNone) ++ return FALSE; ++ + /* Disable output port */ + if (gst_omx_port_set_enabled (self->dec_out_port, FALSE) != OMX_ErrorNone) + return FALSE; +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0002-gstomxvideodec-remove-dead-code.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0002-gstomxvideodec-remove-dead-code.patch new file mode 100644 index 00000000..305e8b20 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0002-gstomxvideodec-remove-dead-code.patch @@ -0,0 +1,99 @@ +From 45a91c687ea3a2ce80fcffcdea413b9dcac55242 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 5 Sep 2013 02:05:52 -0600 +Subject: [PATCH 02/11] gstomxvideodec: remove dead code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This code doesn't seems to be used for quite a while, +remove it before it starts to rot. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideodec.c | 48 +----------------------------------------------- + 1 file changed, 1 insertion(+), 47 deletions(-) + +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index 0d8801e..6b5cbe3 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -1008,19 +1008,13 @@ gst_omx_video_dec_change_state (GstElement * element, GstStateChange transition) + return ret; + } + +-#define MAX_FRAME_DIST_TICKS (5 * OMX_TICKS_PER_SECOND) +-#define MAX_FRAME_DIST_FRAMES (100) +- + static GstVideoCodecFrame * + _find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) + { +- GList *l, *best_l = NULL; +- GList *finish_frames = NULL; + GstVideoCodecFrame *best = NULL; +- guint64 best_timestamp = 0; + guint64 best_diff = G_MAXUINT64; +- BufferIdentification *best_id = NULL; + GList *frames; ++ GList *l; + + frames = gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)); + +@@ -1045,10 +1039,7 @@ _find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) + + if (best == NULL || diff < best_diff) { + best = tmp; +- best_timestamp = timestamp; + best_diff = diff; +- best_l = l; +- best_id = id; + + /* For frames without timestamp we simply take the first frame */ + if ((buf->omx_buf->nTimeStamp == 0 && timestamp == 0) || diff == 0) +@@ -1056,43 +1047,6 @@ _find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) + } + } + +- if (FALSE && best_id) { +- for (l = frames; l && l != best_l; l = l->next) { +- GstVideoCodecFrame *tmp = l->data; +- BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); +- guint64 diff_ticks, diff_frames; +- +- /* This happens for frames that were just added but +- * which were not passed to the component yet. Ignore +- * them here! +- */ +- if (!id) +- continue; +- +- if (id->timestamp > best_timestamp) +- break; +- +- if (id->timestamp == 0 || best_timestamp == 0) +- diff_ticks = 0; +- else +- diff_ticks = best_timestamp - id->timestamp; +- diff_frames = best->system_frame_number - tmp->system_frame_number; +- +- if (diff_ticks > MAX_FRAME_DIST_TICKS +- || diff_frames > MAX_FRAME_DIST_FRAMES) { +- finish_frames = +- g_list_prepend (finish_frames, gst_video_codec_frame_ref (tmp)); +- } +- } +- } +- +- if (FALSE && finish_frames) { +- g_warning ("Too old frames, bug in decoder -- please file a bug"); +- for (l = finish_frames; l; l = l->next) { +- gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), l->data); +- } +- } +- + if (best) + gst_video_codec_frame_ref (best); + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0003-gstomxvideodec-simplify-_find_nearest_frame.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0003-gstomxvideodec-simplify-_find_nearest_frame.patch new file mode 100644 index 00000000..f2c9a912 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0003-gstomxvideodec-simplify-_find_nearest_frame.patch @@ -0,0 +1,125 @@ +From 75402afb7acd7bee4fe02ca2c2e524d3d7426d19 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 5 Sep 2013 02:23:39 -0600 +Subject: [PATCH 03/11] gstomxvideodec: simplify _find_nearest_frame +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +No need to make it more complicated and error prone than +necessary. Also give the function a gst_omx_video_dec prefix +to distinct it from the encoder function. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideodec.c | 60 ++++++++++++++------------------------------------ + 1 file changed, 16 insertions(+), 44 deletions(-) + +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index 6b5cbe3..020b7d3 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -646,18 +646,6 @@ gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component, + return GST_BUFFER_POOL (pool); + } + +-typedef struct _BufferIdentification BufferIdentification; +-struct _BufferIdentification +-{ +- guint64 timestamp; +-}; +- +-static void +-buffer_identification_free (BufferIdentification * id) +-{ +- g_slice_free (BufferIdentification, id); +-} +- + /* prototypes */ + static void gst_omx_video_dec_finalize (GObject * object); + +@@ -1009,40 +997,32 @@ gst_omx_video_dec_change_state (GstElement * element, GstStateChange transition) + } + + static GstVideoCodecFrame * +-_find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) ++gst_omx_video_dec_find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) + { + GstVideoCodecFrame *best = NULL; +- guint64 best_diff = G_MAXUINT64; ++ GstClockTimeDiff best_diff = G_MAXINT64; ++ GstClockTime timestamp; + GList *frames; + GList *l; + ++ if (buf->omx_buf->nTimeStamp) ++ timestamp = ++ gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND, ++ OMX_TICKS_PER_SECOND); ++ else ++ timestamp = GST_CLOCK_TIME_NONE; ++ + frames = gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)); + + for (l = frames; l; l = l->next) { + GstVideoCodecFrame *tmp = l->data; +- BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); +- guint64 timestamp, diff; ++ GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (timestamp, tmp->pts)); + +- /* This happens for frames that were just added but +- * which were not passed to the component yet. Ignore +- * them here! +- */ +- if (!id) +- continue; +- +- timestamp = id->timestamp; +- +- if (timestamp > buf->omx_buf->nTimeStamp) +- diff = timestamp - buf->omx_buf->nTimeStamp; +- else +- diff = buf->omx_buf->nTimeStamp - timestamp; +- +- if (best == NULL || diff < best_diff) { ++ if (diff < best_diff) { + best = tmp; + best_diff = diff; + +- /* For frames without timestamp we simply take the first frame */ +- if ((buf->omx_buf->nTimeStamp == 0 && timestamp == 0) || diff == 0) ++ if (diff == 0) + break; + } + } +@@ -1947,7 +1927,7 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self) + (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp); + + GST_VIDEO_DECODER_STREAM_LOCK (self); +- frame = _find_nearest_frame (self, buf); ++ frame = gst_omx_video_dec_find_nearest_frame (self, buf); + + if (frame + && (deadline = gst_video_decoder_get_max_decode_time +@@ -2926,16 +2906,8 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, + buf->omx_buf->nTickCount = 0; + } + +- if (offset == 0) { +- BufferIdentification *id = g_slice_new0 (BufferIdentification); +- +- if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) +- buf->omx_buf->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; +- +- id->timestamp = buf->omx_buf->nTimeStamp; +- gst_video_codec_frame_set_user_data (frame, id, +- (GDestroyNotify) buffer_identification_free); +- } ++ if (offset == 0 && GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) ++ buf->omx_buf->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + + /* TODO: Set flags + * - OMX_BUFFERFLAG_DECODEONLY for buffers that are outside +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0004-gstomxvideoenc-simplify-_find_nearest_frame.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0004-gstomxvideoenc-simplify-_find_nearest_frame.patch new file mode 100644 index 00000000..b12bac17 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0004-gstomxvideoenc-simplify-_find_nearest_frame.patch @@ -0,0 +1,175 @@ +From 91123307c8f934a867cf70b9ae6b27373311b8fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 5 Sep 2013 03:41:10 -0600 +Subject: [PATCH 04/11] gstomxvideoenc: simplify _find_nearest_frame +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Just the same as we did with the decoder. Also give the +function a gst_omx_video_enc prefix to distinct it from +the decoder function. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideoenc.c | 102 ++++++++------------------------------------------ + 1 file changed, 15 insertions(+), 87 deletions(-) + +diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c +index a85e815..3a139bb 100644 +--- a/omx/gstomxvideoenc.c ++++ b/omx/gstomxvideoenc.c +@@ -55,18 +55,6 @@ gst_omx_video_enc_control_rate_get_type (void) + return qtype; + } + +-typedef struct _BufferIdentification BufferIdentification; +-struct _BufferIdentification +-{ +- guint64 timestamp; +-}; +- +-static void +-buffer_identification_free (BufferIdentification * id) +-{ +- g_slice_free (BufferIdentification, id); +-} +- + /* prototypes */ + static void gst_omx_video_enc_finalize (GObject * object); + static void gst_omx_video_enc_set_property (GObject * object, guint prop_id, +@@ -551,88 +539,34 @@ gst_omx_video_enc_change_state (GstElement * element, GstStateChange transition) + return ret; + } + +-#define MAX_FRAME_DIST_TICKS (5 * OMX_TICKS_PER_SECOND) +-#define MAX_FRAME_DIST_FRAMES (100) +- + static GstVideoCodecFrame * +-_find_nearest_frame (GstOMXVideoEnc * self, GstOMXBuffer * buf) ++gst_omx_video_enc_find_nearest_frame (GstOMXVideoEnc * self, GstOMXBuffer * buf) + { +- GList *l, *best_l = NULL; +- GList *finish_frames = NULL; + GstVideoCodecFrame *best = NULL; +- guint64 best_timestamp = 0; +- guint64 best_diff = G_MAXUINT64; +- BufferIdentification *best_id = NULL; ++ GstClockTimeDiff best_diff = G_MAXINT64; ++ GstClockTime timestamp; + GList *frames; ++ GList *l; ++ ++ if (buf->omx_buf->nTimeStamp) ++ timestamp = ++ gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND, ++ OMX_TICKS_PER_SECOND); ++ else ++ timestamp = GST_CLOCK_TIME_NONE; + + frames = gst_video_encoder_get_frames (GST_VIDEO_ENCODER (self)); + + for (l = frames; l; l = l->next) { + GstVideoCodecFrame *tmp = l->data; +- BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); +- guint64 timestamp, diff; +- +- /* This happens for frames that were just added but +- * which were not passed to the component yet. Ignore +- * them here! +- */ +- if (!id) +- continue; +- +- timestamp = id->timestamp; ++ GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (timestamp, tmp->pts)); + +- if (timestamp > buf->omx_buf->nTimeStamp) +- diff = timestamp - buf->omx_buf->nTimeStamp; +- else +- diff = buf->omx_buf->nTimeStamp - timestamp; +- +- if (best == NULL || diff < best_diff) { ++ if (diff < best_diff) { + best = tmp; +- best_timestamp = timestamp; + best_diff = diff; +- best_l = l; +- best_id = id; +- +- /* For frames without timestamp we simply take the first frame */ +- if ((buf->omx_buf->nTimeStamp == 0 && timestamp == 0) || diff == 0) +- break; +- } +- } +- +- if (best_id) { +- for (l = frames; l && l != best_l; l = l->next) { +- GstVideoCodecFrame *tmp = l->data; +- BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); +- guint64 diff_ticks, diff_frames; +- +- /* This happens for frames that were just added but +- * which were not passed to the component yet. Ignore +- * them here! +- */ +- if (!id) +- continue; + +- if (id->timestamp > best_timestamp) ++ if (diff == 0) + break; +- +- if (id->timestamp == 0 || best_timestamp == 0) +- diff_ticks = 0; +- else +- diff_ticks = best_timestamp - id->timestamp; +- diff_frames = best->system_frame_number - tmp->system_frame_number; +- +- if (diff_ticks > MAX_FRAME_DIST_TICKS +- || diff_frames > MAX_FRAME_DIST_FRAMES) { +- finish_frames = +- g_list_prepend (finish_frames, gst_video_codec_frame_ref (tmp)); +- } +- } +- } +- +- if (finish_frames) { +- g_warning ("Too old frames, bug in encoder -- please file a bug"); +- for (l = finish_frames; l; l = l->next) { +- gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (self), l->data); + } + } + +@@ -851,7 +785,7 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self) + (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp); + + GST_VIDEO_ENCODER_STREAM_LOCK (self); +- frame = _find_nearest_frame (self, buf); ++ frame = gst_omx_video_enc_find_nearest_frame (self, buf); + + g_assert (klass->handle_output_frame); + flow_ret = klass->handle_output_frame (self, self->enc_out_port, buf, frame); +@@ -1559,7 +1493,6 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, + port = self->enc_in_port; + + while (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) { +- BufferIdentification *id; + GstClockTime timestamp, duration; + + /* Make sure to release the base class stream lock, otherwise +@@ -1683,11 +1616,6 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, + self->last_upstream_ts += duration; + } + +- id = g_slice_new0 (BufferIdentification); +- id->timestamp = buf->omx_buf->nTimeStamp; +- gst_video_codec_frame_set_user_data (frame, id, +- (GDestroyNotify) buffer_identification_free); +- + self->started = TRUE; + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0005-omx-improve-tunneling-support.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0005-omx-improve-tunneling-support.patch new file mode 100644 index 00000000..686e0693 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0005-omx-improve-tunneling-support.patch @@ -0,0 +1,77 @@ +From 1975efe159dc52a8030602736c5319785fb62329 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 5 Sep 2013 04:15:26 -0600 +Subject: [PATCH 05/11] omx: improve tunneling support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Keep track where the tunnel leads us instead of just if it's tunneled or not. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomx.c | 13 +++++++------ + omx/gstomx.h | 2 +- + 2 files changed, 8 insertions(+), 7 deletions(-) + +diff --git a/omx/gstomx.c b/omx/gstomx.c +index 4e94712..c8a8927 100644 +--- a/omx/gstomx.c ++++ b/omx/gstomx.c +@@ -920,7 +920,7 @@ gst_omx_component_add_port (GstOMXComponent * comp, guint32 index) + port->comp = comp; + port->index = index; + +- port->tunneled = FALSE; ++ port->tunneled = NULL; + + port->port_def = port_def; + +@@ -1085,8 +1085,8 @@ gst_omx_component_setup_tunnel (GstOMXComponent * comp1, GstOMXPort * port1, + port2->index); + + if (err == OMX_ErrorNone) { +- port1->tunneled = TRUE; +- port2->tunneled = TRUE; ++ port1->tunneled = port2; ++ port2->tunneled = port1; + } + + GST_DEBUG_OBJECT (comp1->parent, +@@ -1115,7 +1115,8 @@ gst_omx_component_close_tunnel (GstOMXComponent * comp1, GstOMXPort * port1, + g_return_val_if_fail (port2->port_def.eDir == OMX_DirInput, + OMX_ErrorUndefined); + g_return_val_if_fail (comp1->core == comp2->core, OMX_ErrorUndefined); +- g_return_val_if_fail (port1->tunneled && port2->tunneled, OMX_ErrorUndefined); ++ g_return_val_if_fail (port1->tunneled == port2, OMX_ErrorUndefined); ++ g_return_val_if_fail (port2->tunneled == port1, OMX_ErrorUndefined); + + g_mutex_lock (&comp1->lock); + g_mutex_lock (&comp2->lock); +@@ -1136,8 +1137,8 @@ gst_omx_component_close_tunnel (GstOMXComponent * comp1, GstOMXPort * port1, + gst_omx_error_to_string (err), err); + } + +- port1->tunneled = FALSE; +- port2->tunneled = FALSE; ++ port1->tunneled = NULL; ++ port2->tunneled = NULL; + + GST_DEBUG_OBJECT (comp1->parent, + "Closed tunnel between %s port %u and %s port %u", +diff --git a/omx/gstomx.h b/omx/gstomx.h +index 8af81b8..3645b63 100644 +--- a/omx/gstomx.h ++++ b/omx/gstomx.h +@@ -199,7 +199,7 @@ struct _GstOMXPort { + GstOMXComponent *comp; + guint32 index; + +- gboolean tunneled; ++ GstOMXPort *tunneled; + + OMX_PARAM_PORTDEFINITIONTYPE port_def; + GPtrArray *buffers; /* Contains GstOMXBuffer* */ +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0006-omx-add-tunneling-support-between-decoder-and-encode.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0006-omx-add-tunneling-support-between-decoder-and-encode.patch new file mode 100644 index 00000000..aa3e403f --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0006-omx-add-tunneling-support-between-decoder-and-encode.patch @@ -0,0 +1,328 @@ +From 17e9d641799a075a085a64d0543c5a51b11fd73d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Fri, 13 Sep 2013 03:33:19 -0600 +Subject: [PATCH 06/11] omx: add tunneling support between decoder and + encoders v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Forward the frames through both the OMX tunnel as well as the gst pad, this +way we can map OMX buffers to their frame counterpart when they left the +tunnel on the other side. + +v2: fix tunnel close and buffer dealloc order + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomx.c | 6 +++- + omx/gstomx.h | 2 ++ + omx/gstomxvideodec.c | 90 ++++++++++++++++++++++++++++++++++++++++++++------ + omx/gstomxvideoenc.c | 29 +++++++++++++--- + 4 files changed, 110 insertions(+), 17 deletions(-) + +diff --git a/omx/gstomx.c b/omx/gstomx.c +index c8a8927..df3a8ff 100644 +--- a/omx/gstomx.c ++++ b/omx/gstomx.c +@@ -1204,7 +1204,6 @@ gst_omx_port_acquire_buffer (GstOMXPort * port, GstOMXBuffer ** buf) + GstOMXBuffer *_buf = NULL; + + g_return_val_if_fail (port != NULL, GST_OMX_ACQUIRE_BUFFER_ERROR); +- g_return_val_if_fail (!port->tunneled, GST_OMX_ACQUIRE_BUFFER_ERROR); + g_return_val_if_fail (buf != NULL, GST_OMX_ACQUIRE_BUFFER_ERROR); + + *buf = NULL; +@@ -1298,6 +1297,11 @@ retry: + goto done; + } + ++ if (port->tunneled) { ++ ret = GST_OMX_ACQUIRE_BUFFER_TUNNELED; ++ goto done; ++ } ++ + /* + * At this point we have no error or flushing/eos port + * and a properly configured port. +diff --git a/omx/gstomx.h b/omx/gstomx.h +index 3645b63..9b534bd 100644 +--- a/omx/gstomx.h ++++ b/omx/gstomx.h +@@ -124,6 +124,8 @@ typedef enum { + GST_OMX_ACQUIRE_BUFFER_RECONFIGURE, + /* The port is EOS */ + GST_OMX_ACQUIRE_BUFFER_EOS, ++ /* The port is tunneled */ ++ GST_OMX_ACQUIRE_BUFFER_TUNNELED, + /* A fatal error happened */ + GST_OMX_ACQUIRE_BUFFER_ERROR + } GstOMXAcquireBufferReturn; +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index 020b7d3..e8813fb 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -50,6 +50,7 @@ + #include <string.h> + + #include "gstomxvideodec.h" ++#include "gstomxvideoenc.h" + + GST_DEBUG_CATEGORY_STATIC (gst_omx_video_dec_debug_category); + #define GST_CAT_DEFAULT gst_omx_video_dec_debug_category +@@ -881,6 +882,11 @@ gst_omx_video_dec_shutdown (GstOMXVideoDec * self) + gst_omx_component_get_state (self->dec, 5 * GST_SECOND); + } + ++ if (self->dec_out_port->tunneled) { ++ gst_omx_component_close_tunnel (self->dec, self->dec_out_port, ++ self->dec_out_port->tunneled->comp, self->dec_out_port->tunneled); ++ } ++ + return TRUE; + } + +@@ -1527,7 +1533,7 @@ done: + static OMX_ERRORTYPE + gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec * self) + { +- OMX_ERRORTYPE err; ++ OMX_ERRORTYPE err = OMX_ErrorNone; + + if (self->out_port_pool) { + gst_buffer_pool_set_active (self->out_port_pool, FALSE); +@@ -1543,7 +1549,10 @@ gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec * self) + gst_omx_port_deallocate_buffers (self-> + eglimage ? self->egl_out_port : self->dec_out_port); + #else +- err = gst_omx_port_deallocate_buffers (self->dec_out_port); ++ if (!self->dec_out_port->tunneled) ++ err = gst_omx_port_deallocate_buffers (self->dec_out_port); ++ else ++ err = gst_omx_port_set_enabled (self->dec_out_port, FALSE); + #endif + + return err; +@@ -1772,12 +1781,28 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self) + + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + ++ { ++ GstPad *peer = gst_pad_get_peer (GST_VIDEO_DECODER_SRC_PAD (self)); ++ GstElement *element = peer ? gst_pad_get_parent_element (peer) : NULL; ++ ++ if (element && GST_IS_OMX_VIDEO_ENC (element)) { ++ GstOMXVideoEnc *enc = GST_OMX_VIDEO_ENC (element); ++ ++ gst_omx_component_setup_tunnel (self->dec, self->dec_out_port, ++ enc->enc, enc->enc_in_port); ++ ++ } ++ } ++ + #if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL) + enable_port: + #endif +- err = gst_omx_video_dec_allocate_output_buffers (self); +- if (err != OMX_ErrorNone) +- goto done; ++ ++ if (!self->dec_out_port->tunneled) { ++ err = gst_omx_video_dec_allocate_output_buffers (self); ++ if (err != OMX_ErrorNone) ++ goto done; ++ } + + err = gst_omx_port_populate (port); + if (err != OMX_ErrorNone) +@@ -1816,6 +1841,9 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self) + goto flushing; + } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_EOS) { + goto eos; ++ } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_TUNNELED) { ++ gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); ++ return; + } + + if (!gst_pad_has_current_caps (GST_VIDEO_DECODER_SRC_PAD (self)) || +@@ -2657,6 +2685,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder, + GST_DEBUG_OBJECT (self, "Starting task again"); + + self->downstream_flow_ret = GST_FLOW_OK; ++ + gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_omx_video_dec_loop, decoder, NULL); + +@@ -2703,6 +2732,7 @@ gst_omx_video_dec_reset (GstVideoDecoder * decoder, gboolean hard) + self->last_upstream_ts = 0; + self->eos = FALSE; + self->downstream_flow_ret = GST_FLOW_OK; ++ + gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_omx_video_dec_loop, decoder, NULL); + +@@ -2925,7 +2955,11 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, + goto release_error; + } + +- gst_video_codec_frame_unref (frame); ++ if (self->dec_out_port->tunneled) { ++ frame->output_buffer = gst_buffer_new (); ++ gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame); ++ } else ++ gst_video_codec_frame_unref (frame); + + GST_DEBUG_OBJECT (self, "Passed frame to component"); + +@@ -3003,6 +3037,7 @@ gst_omx_video_dec_finish (GstVideoDecoder * decoder) + static GstFlowReturn + gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + { ++ GstOMXVideoEnc *enc = NULL; + GstOMXVideoDecClass *klass; + GstOMXBuffer *buf; + GstOMXAcquireBufferReturn acq_ret; +@@ -3031,6 +3066,14 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + return GST_FLOW_OK; + } + ++ if (self->dec_out_port->tunneled) { ++ GstPad *peer = gst_pad_get_peer (GST_VIDEO_DECODER_SRC_PAD (self)); ++ GstElement *element = peer ? gst_pad_get_parent_element (peer) : NULL; ++ ++ if (element && GST_IS_OMX_VIDEO_ENC (element)) ++ enc = GST_OMX_VIDEO_ENC (element); ++ } ++ + /* Make sure to release the base class stream lock, otherwise + * _loop() can't call _finish_frame() and we might block forever + * because no input buffers are released */ +@@ -3047,8 +3090,14 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + return GST_FLOW_ERROR; + } + +- g_mutex_lock (&self->drain_lock); +- self->draining = TRUE; ++ if (enc) { ++ g_mutex_lock (&enc->drain_lock); ++ enc->draining = TRUE; ++ } else { ++ g_mutex_lock (&self->drain_lock); ++ self->draining = TRUE; ++ } ++ + buf->omx_buf->nFilledLen = 0; + buf->omx_buf->nTimeStamp = + gst_util_uint64_scale (self->last_upstream_ts, OMX_TICKS_PER_SECOND, +@@ -3059,6 +3108,10 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Failed to drain component: %s (0x%08x)", + gst_omx_error_to_string (err), err); ++ if (enc) ++ g_mutex_unlock (&enc->drain_lock); ++ else ++ g_mutex_unlock (&self->drain_lock); + GST_VIDEO_DECODER_STREAM_LOCK (self); + return GST_FLOW_ERROR; + } +@@ -3067,18 +3120,33 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + + if (G_UNLIKELY (self->dec->hacks & GST_OMX_HACK_DRAIN_MAY_NOT_RETURN)) { + gint64 wait_until = g_get_monotonic_time () + G_TIME_SPAN_SECOND / 2; ++ gboolean result; ++ ++ if (enc) ++ result = ++ g_cond_wait_until (&enc->drain_cond, &enc->drain_lock, wait_until); ++ else ++ result = ++ g_cond_wait_until (&self->drain_cond, &self->drain_lock, wait_until); + +- if (!g_cond_wait_until (&self->drain_cond, &self->drain_lock, wait_until)) ++ if (!result) + GST_WARNING_OBJECT (self, "Drain timed out"); + else + GST_DEBUG_OBJECT (self, "Drained component"); + + } else { +- g_cond_wait (&self->drain_cond, &self->drain_lock); ++ if (enc) ++ g_cond_wait (&enc->drain_cond, &enc->drain_lock); ++ else ++ g_cond_wait (&self->drain_cond, &self->drain_lock); + GST_DEBUG_OBJECT (self, "Drained component"); + } + +- g_mutex_unlock (&self->drain_lock); ++ if (enc) ++ g_mutex_unlock (&enc->drain_lock); ++ else ++ g_mutex_unlock (&self->drain_lock); ++ + GST_VIDEO_DECODER_STREAM_LOCK (self); + + self->started = FALSE; +diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c +index 3a139bb..8f6cab3 100644 +--- a/omx/gstomxvideoenc.c ++++ b/omx/gstomxvideoenc.c +@@ -364,7 +364,10 @@ gst_omx_video_enc_shutdown (GstOMXVideoEnc * self) + gst_omx_component_get_state (self->enc, 5 * GST_SECOND); + } + gst_omx_component_set_state (self->enc, OMX_StateLoaded); +- gst_omx_port_deallocate_buffers (self->enc_in_port); ++ if (!self->enc_in_port->tunneled) ++ gst_omx_port_deallocate_buffers (self->enc_in_port); ++ else ++ gst_omx_port_set_enabled (self->enc_in_port, FALSE); + gst_omx_port_deallocate_buffers (self->enc_out_port); + if (state > OMX_StateLoaded) + gst_omx_component_get_state (self->enc, 5 * GST_SECOND); +@@ -1086,8 +1089,9 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder, + if (gst_omx_port_wait_buffers_released (self->enc_out_port, + 1 * GST_SECOND) != OMX_ErrorNone) + return FALSE; +- if (gst_omx_port_deallocate_buffers (self->enc_in_port) != OMX_ErrorNone) +- return FALSE; ++ if (!self->enc_in_port->tunneled) ++ if (gst_omx_port_deallocate_buffers (self->enc_in_port) != OMX_ErrorNone) ++ return FALSE; + if (gst_omx_port_deallocate_buffers (self->enc_out_port) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_wait_enabled (self->enc_in_port, +@@ -1225,8 +1229,18 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder, + return FALSE; + + /* Need to allocate buffers to reach Idle state */ +- if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone) +- return FALSE; ++ if (self->enc_in_port->tunneled) { ++ if (gst_omx_port_set_enabled (self->enc_in_port->tunneled, ++ TRUE) != OMX_ErrorNone) ++ return FALSE; ++ ++ if (gst_omx_port_wait_enabled (self->enc_in_port->tunneled, ++ 1 * GST_SECOND) != OMX_ErrorNone) ++ return FALSE; ++ } else { ++ if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone) ++ return FALSE; ++ } + + if (gst_omx_component_get_state (self->enc, + GST_CLOCK_TIME_NONE) != OMX_StateIdle) +@@ -1492,6 +1506,11 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, + + port = self->enc_in_port; + ++ if (port->tunneled) { ++ gst_video_codec_frame_unref (frame); ++ return self->downstream_flow_ret; ++ } ++ + while (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) { + GstClockTime timestamp, duration; + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0007-gstomxvideoenc-implement-scaling-configuration-suppo.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0007-gstomxvideoenc-implement-scaling-configuration-suppo.patch new file mode 100644 index 00000000..6db5e742 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0007-gstomxvideoenc-implement-scaling-configuration-suppo.patch @@ -0,0 +1,155 @@ +From 9d1fc5ceb72222037b959c1a2c3fe05c50de676a Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Thu, 14 Nov 2013 18:47:24 -0500 +Subject: [PATCH 07/11] gstomxvideoenc: implement scaling configuration + support + +Signed-off-by: Leo Liu <leo.liu@amd.com> +--- + omx/gstomxvideoenc.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++- + omx/gstomxvideoenc.h | 3 +++ + 2 files changed, 75 insertions(+), 1 deletion(-) + +diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c +index 8f6cab3..ee41fa0 100644 +--- a/omx/gstomxvideoenc.c ++++ b/omx/gstomxvideoenc.c +@@ -96,7 +96,9 @@ enum + PROP_TARGET_BITRATE, + PROP_QUANT_I_FRAMES, + PROP_QUANT_P_FRAMES, +- PROP_QUANT_B_FRAMES ++ PROP_QUANT_B_FRAMES, ++ PROP_SCALING_WIDTH, ++ PROP_SCALING_HEIGHT + }; + + /* FIXME: Better defaults */ +@@ -105,6 +107,8 @@ enum + #define GST_OMX_VIDEO_ENC_QUANT_I_FRAMES_DEFAULT (0xffffffff) + #define GST_OMX_VIDEO_ENC_QUANT_P_FRAMES_DEFAULT (0xffffffff) + #define GST_OMX_VIDEO_ENC_QUANT_B_FRAMES_DEFAULT (0xffffffff) ++#define GST_OMX_VIDEO_ENC_SCALING_WIDTH_DEFAULT (0xffffffff) ++#define GST_OMX_VIDEO_ENC_SCALING_HEIGHT_DEFAULT (0xffffffff) + + /* class initialization */ + +@@ -163,6 +167,20 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass) + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY)); + ++ g_object_class_install_property (gobject_class, PROP_SCALING_WIDTH, ++ g_param_spec_uint ("scaling-width", "Scaling Width", ++ "Scaling Width parameter (0xffffffff=component default)", ++ 0, G_MAXUINT, GST_OMX_VIDEO_ENC_SCALING_WIDTH_DEFAULT, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | ++ GST_PARAM_MUTABLE_READY)); ++ ++ g_object_class_install_property (gobject_class, PROP_SCALING_HEIGHT, ++ g_param_spec_uint ("scaling-height", "Scaling Height", ++ "Scaling Height parameter (0xffffffff=component default)", ++ 0, G_MAXUINT, GST_OMX_VIDEO_ENC_SCALING_HEIGHT_DEFAULT, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | ++ GST_PARAM_MUTABLE_READY)); ++ + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_omx_video_enc_change_state); + +@@ -197,6 +215,8 @@ gst_omx_video_enc_init (GstOMXVideoEnc * self) + self->quant_i_frames = GST_OMX_VIDEO_ENC_QUANT_I_FRAMES_DEFAULT; + self->quant_p_frames = GST_OMX_VIDEO_ENC_QUANT_P_FRAMES_DEFAULT; + self->quant_b_frames = GST_OMX_VIDEO_ENC_QUANT_B_FRAMES_DEFAULT; ++ self->scaling_width = GST_OMX_VIDEO_ENC_SCALING_WIDTH_DEFAULT; ++ self->scaling_height = GST_OMX_VIDEO_ENC_SCALING_HEIGHT_DEFAULT; + + g_mutex_init (&self->drain_lock); + g_cond_init (&self->drain_cond); +@@ -345,6 +365,45 @@ gst_omx_video_enc_open (GstVideoEncoder * encoder) + + } + } ++ ++ if (self->scaling_width != 0xffffffff || ++ self->scaling_height != 0xffffffff) { ++ OMX_CONFIG_SCALEFACTORTYPE scale_factor; ++ GST_OMX_INIT_STRUCT (&scale_factor); ++ scale_factor.nPortIndex = self->enc_out_port->index; ++ ++ err = gst_omx_component_get_config (self->enc, ++ OMX_IndexConfigCommonScale, &scale_factor); ++ ++ if (err == OMX_ErrorNone) { ++ ++ if (self->scaling_width != 0xffffffff) ++ scale_factor.xWidth = self->scaling_width; ++ if (self->scaling_height != 0xffffffff) ++ scale_factor.xHeight = self->scaling_height; ++ ++ err = ++ gst_omx_component_set_config (self->enc, ++ OMX_IndexConfigCommonScale, &scale_factor); ++ if (err == OMX_ErrorUnsupportedIndex) { ++ GST_WARNING_OBJECT (self, ++ "Setting scale configuration not supported by the component"); ++ } else if (err == OMX_ErrorUnsupportedSetting) { ++ GST_WARNING_OBJECT (self, ++ "Setting scale configuration %u %u not supported by the component", ++ self->scaling_width, self->scaling_height); ++ } else if (err != OMX_ErrorNone) { ++ GST_ERROR_OBJECT (self, ++ "Failed to set scale configuration: %s (0x%08x)", ++ gst_omx_error_to_string (err), err); ++ return FALSE; ++ } ++ } else { ++ GST_ERROR_OBJECT (self, ++ "Failed to set scale configuration: %s (0x%08x)", ++ gst_omx_error_to_string (err), err); ++ } ++ } + } + + return TRUE; +@@ -443,6 +502,12 @@ gst_omx_video_enc_set_property (GObject * object, guint prop_id, + case PROP_QUANT_B_FRAMES: + self->quant_b_frames = g_value_get_uint (value); + break; ++ case PROP_SCALING_WIDTH: ++ self->scaling_width = g_value_get_uint (value); ++ break; ++ case PROP_SCALING_HEIGHT: ++ self->scaling_height = g_value_get_uint (value); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -471,6 +536,12 @@ gst_omx_video_enc_get_property (GObject * object, guint prop_id, GValue * value, + case PROP_QUANT_B_FRAMES: + g_value_set_uint (value, self->quant_b_frames); + break; ++ case PROP_SCALING_WIDTH: ++ g_value_set_uint (value, self->scaling_width); ++ break; ++ case PROP_SCALING_HEIGHT: ++ g_value_set_uint (value, self->scaling_height); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +diff --git a/omx/gstomxvideoenc.h b/omx/gstomxvideoenc.h +index e266537..86e9c8f 100644 +--- a/omx/gstomxvideoenc.h ++++ b/omx/gstomxvideoenc.h +@@ -77,6 +77,9 @@ struct _GstOMXVideoEnc + guint32 quant_p_frames; + guint32 quant_b_frames; + ++ guint32 scaling_width; ++ guint32 scaling_height; ++ + GstFlowReturn downstream_flow_ret; + }; + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0008-configure-fix-first-run-of-autogen-automake.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0008-configure-fix-first-run-of-autogen-automake.patch new file mode 100644 index 00000000..8478cc3a --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0008-configure-fix-first-run-of-autogen-automake.patch @@ -0,0 +1,29 @@ +From 8e089ae8249899b8e47cbe7abfe3dd8814458c89 Mon Sep 17 00:00:00 2001 +From: Tim Writer <Tim.Writer@amd.com> +Date: Mon, 25 Nov 2013 15:51:21 -0500 +Subject: [PATCH 08/11] configure: fix first run of autogen/automake + +Without AC_CONFIG_AUX_DIR, libtoolize fails to copy ltmain.sh, +causing the first run of automake to fail. +--- + configure.ac | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/configure.ac b/configure.ac +index fcf4d9d..6dcca1c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -9,6 +9,10 @@ AC_INIT(GStreamer OpenMAX Plug-ins, 1.0.0.1, + http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer, + gst-omx) + ++dnl Forces libtoolize to copy ltmain.sh. Without it, automake fails on ++dnl the first run. ++AC_CONFIG_AUX_DIR([.]) ++ + AG_GST_INIT + + dnl initialize automake +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0009-omxvideodec-fix-startup-race-condition.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0009-omxvideodec-fix-startup-race-condition.patch new file mode 100644 index 00000000..df070f44 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0009-omxvideodec-fix-startup-race-condition.patch @@ -0,0 +1,33 @@ +From c79c13c43e4d535fdb0c7fc508a7d5219eebe940 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Sat, 1 Mar 2014 18:48:17 +0100 +Subject: [PATCH 09/11] omxvideodec: fix startup race condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The reset function shouldn't start the src pad +loop if it wasn't started before. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideodec.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index e8813fb..00f3951 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -2703,6 +2703,9 @@ gst_omx_video_dec_reset (GstVideoDecoder * decoder, gboolean hard) + + GST_DEBUG_OBJECT (self, "Resetting decoder"); + ++ if (gst_omx_component_get_state (self->dec, 0) == OMX_StateLoaded) ++ return TRUE; ++ + gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE); + gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE); + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideoenc-fix-startup-race-condition.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideoenc-fix-startup-race-condition.patch new file mode 100644 index 00000000..68b89b8a --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideoenc-fix-startup-race-condition.patch @@ -0,0 +1,33 @@ +From ba51373c66f4c9c3349eb083c5218b31e4162a6e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Sat, 1 Mar 2014 18:49:41 +0100 +Subject: [PATCH 10/11] omxvideoenc: fix startup race condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The reset function shouldn't start the src pad +loop if it wasn't started before. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideoenc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c +index ee41fa0..e65a9e0 100644 +--- a/omx/gstomxvideoenc.c ++++ b/omx/gstomxvideoenc.c +@@ -1359,6 +1359,9 @@ gst_omx_video_enc_reset (GstVideoEncoder * encoder, gboolean hard) + + GST_DEBUG_OBJECT (self, "Resetting encoder"); + ++ if (gst_omx_component_get_state (self->enc, 0) == OMX_StateLoaded) ++ return TRUE; ++ + gst_omx_port_set_flushing (self->enc_in_port, 5 * GST_SECOND, TRUE); + gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, TRUE); + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0011-omx-fix-two-serious-message-handling-bugs.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0011-omx-fix-two-serious-message-handling-bugs.patch new file mode 100644 index 00000000..6de3b84a --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0011-omx-fix-two-serious-message-handling-bugs.patch @@ -0,0 +1,40 @@ +From 6d0b6813745b54eb5dd249ba4446118b21383059 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Sat, 1 Mar 2014 22:28:24 +0100 +Subject: [PATCH 11/11] omx: fix two serious message handling bugs + +Waiting for the next message if we already got one +is nonsense and can lead to lockups. + +https://bugzilla.gnome.org/show_bug.cgi?id=725468 +--- + omx/gstomx.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/omx/gstomx.c b/omx/gstomx.c +index df3a8ff..b77c904 100644 +--- a/omx/gstomx.c ++++ b/omx/gstomx.c +@@ -842,8 +842,7 @@ gst_omx_component_get_state (GstOMXComponent * comp, GstClockTime timeout) + g_mutex_unlock (&comp->lock); + if (!g_queue_is_empty (&comp->messages)) { + signalled = TRUE; +- } +- if (timeout == GST_CLOCK_TIME_NONE) { ++ } else if (timeout == GST_CLOCK_TIME_NONE) { + g_cond_wait (&comp->messages_cond, &comp->messages_lock); + signalled = TRUE; + } else { +@@ -1519,8 +1518,7 @@ gst_omx_port_set_flushing (GstOMXPort * port, GstClockTime timeout, + + if (!g_queue_is_empty (&comp->messages)) { + signalled = TRUE; +- } +- if (timeout == GST_CLOCK_TIME_NONE) { ++ } else if (timeout == GST_CLOCK_TIME_NONE) { + g_cond_wait (&comp->messages_cond, &comp->messages_lock); + signalled = TRUE; + } else { +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx_git.bbappend b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx_git.bbappend new file mode 100644 index 00000000..7464a6da --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx_git.bbappend @@ -0,0 +1,32 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +# +# Remove the patch as it is not needed with the new SRCREV we are using +# +SRC_URI := "${@oe_filter_out('file://0001-omx-fixed-type-error-in-printf-call.patch', '${SRC_URI}', d)}" + +SRC_URI += "file://0001-gstomxvideodec-fix-multithreads-negotiation-problem-.patch \ + file://0002-gstomxvideodec-remove-dead-code.patch \ + file://0003-gstomxvideodec-simplify-_find_nearest_frame.patch \ + file://0004-gstomxvideoenc-simplify-_find_nearest_frame.patch \ + file://0005-omx-improve-tunneling-support.patch \ + file://0006-omx-add-tunneling-support-between-decoder-and-encode.patch \ + file://0007-gstomxvideoenc-implement-scaling-configuration-suppo.patch \ + file://0008-configure-fix-first-run-of-autogen-automake.patch \ + file://0009-omxvideodec-fix-startup-race-condition.patch \ + file://0010-omxvideoenc-fix-startup-race-condition.patch \ + file://0011-omx-fix-two-serious-message-handling-bugs.patch \ + " + +SRCREV = "c44cd849400b90f5f4b1f4f429278d9685b1daca" + +PV .= "+git${SRCPV}" + +EXTRA_OECONF += "--with-omx-target=bellagio" + +# +# This package should not have commercial license flags. +# There is discussion in the OE community about fixing this +# but in the meantime we'll explicitly remove it here. +# +LICENSE_FLAGS := "${@oe_filter_out('commercial', '${LICENSE_FLAGS}', d)}" diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend new file mode 100644 index 00000000..ee510f63 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend @@ -0,0 +1 @@ +PACKAGECONFIG[bluez] = "--enable-bluez,--disable-bluez,bluez5" diff --git a/meta-steppeeagle/recipes-multimedia/libomxil/libomxil_0.9.3.bbappend b/meta-steppeeagle/recipes-multimedia/libomxil/libomxil_0.9.3.bbappend new file mode 100644 index 00000000..068e3f2c --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/libomxil/libomxil_0.9.3.bbappend @@ -0,0 +1,8 @@ +RDEPENDS_${PN} += "libomx-mesa" + +# +# This package should not have commercial license flags. +# There is discussion in the OE community about fixing this +# but in the meantime we'll explicitly remove it here. +# +LICENSE_FLAGS := "${@oe_filter_out('commercial', '${LICENSE_FLAGS}', d)}" |