From b6b1cda6a526bad8c7f50aa4427bedbc6e539a4d Mon Sep 17 00:00:00 2001 From: Artem Senichev Date: Fri, 23 Nov 2018 10:31:59 +0300 Subject: [PATCH] Replace ColdFire FSI with plain FSI-over-GPIO Workaround to fix ColdFire FSI performance issue: https://github.com/openbmc/openbmc/issues/3433 Current implementation based on an old version of skeleton (revision 517b35ed92ad2c0df5e048711c175bacb632f6d0), mostly it's a copy-paste of op-hostctl module. Signed-off-by: Artem Senichev Signed-off-by: Alexander Filippov --- control_host_obj.c | 259 ++++++++++++++++++++-------------- 1 file changed, 152 insertions(+), 107 deletions(-) diff --git a/control_host_obj.c b/control_host_obj.c index 27f7fc7..ca45182 100644 --- a/control_host_obj.c +++ b/control_host_obj.c @@ -5,10 +5,10 @@ #include #include #include -#include - #include #include +#include +#include /* ------------------------------------------------------------------------- */ static const gchar* dbus_object_path = "/org/openbmc/control"; @@ -17,36 +17,31 @@ static const gchar* dbus_name = "org.openbmc.control.Host"; static GDBusObjectManagerServer *manager = NULL; -#define PPC_BIT32(bit) (0x80000000UL >> (bit)) - -#define FSI_EXTERNAL_MODE_PATH "/sys/devices/platform/gpio-fsi/external_mode" -#define FSI_SCAN_PATH "/sys/devices/platform/gpio-fsi/fsi0/rescan" - -/* TODO: Change this over to the cfam path once the cfam chardev patches have landed */ -#define FSI_RAW_PATH "/sys/devices/platform/gpio-fsi/fsi0/slave@00:00/raw" - -#define FSI_SCAN_DELAY_US 10000 +static GPIO* fsi_data; +static GPIO* fsi_clk; +static GPIO* fsi_enable; +static GPIO* cronus_sel; +static size_t num_optionals; +static GPIO* optionals; +static gboolean* optional_pols; -/* Attention registers */ -#define FSI_A_SI1S 0x081c -#define TRUE_MASK 0x100d -#define INTERRUPT_STATUS_REG 0x100b +/* Bit bang patterns */ -/* SBE boot register and values */ -#define SBE_VITAL 0x281c -#define SBE_WARMSTART PPC_BIT32(0) -#define SBE_HW_TRIGGER PPC_BIT32(2) -#define SBE_UPDATE_1ST_NIBBLE PPC_BIT32(3) -#define SBE_IMAGE_SELECT PPC_BIT32(8) -#define SBE_UPDATE_3RD_NIBBLE PPC_BIT32(11) +//putcfam pu 281c 30000000 -p0 (Primary Side Select) +static const char* primary = "000011111111110101111000111001100111111111111111111111111111101111111111"; +//putcfam pu 281c B0000000 -p0 +static const char* go = "000011111111110101111000111000100111111111111111111111111111101101111111"; +//putcfam pu 0x281c 30900000 (Golden Side Select) +static const char* golden = "000011111111110101111000111001100111101101111111111111111111101001111111"; -/* Once the side is selected and attention bits are set, this starts the SBE */ -#define START_SBE (SBE_WARMSTART | SBE_HW_TRIGGER | SBE_UPDATE_1ST_NIBBLE) +/* Setup attentions */ +//putcfam pu 0x081C 20000000 +static const char* attnA = "000011111111111101111110001001101111111111111111111111111111110001111111"; +//putcfam pu 0x100D 40000000 +static const char* attnB = "000011111111111011111100101001011111111111111111111111111111110001111111"; +//putcfam pu 0x100B FFFFFFFF +static const char* attnC = "000011111111111011111101001000000000000000000000000000000000001011111111"; -/* Primary is first side. Golden is second side */ -#define PRIMARY_SIDE (SBE_HW_TRIGGER | SBE_UPDATE_1ST_NIBBLE) -#define GOLDEN_SIDE (SBE_HW_TRIGGER | SBE_UPDATE_1ST_NIBBLE | \ - SBE_IMAGE_SELECT | SBE_UPDATE_3RD_NIBBLE) static gboolean on_init(Control *control, @@ -57,126 +52,147 @@ on_init(Control *control, return TRUE; } -static gint -fsi_putcfam(int fd, uint64_t addr64, uint32_t val_host) +int gpio_clock_cycle(GPIO* gpio, int num_clks) { - int rc; - uint32_t val = htobe32(val_host); - /* Map FSI to FSI_BYTE, as the 'raw' kernel interface expects this */ - uint32_t addr = (addr64 & 0x7ffc00) | ((addr64 & 0x3ff) << 2); - - rc = lseek(fd, addr, SEEK_SET); - if (rc < 0) { - g_print("ERROR HostControl: cfam seek failed (0x%08x): %s\n", addr, - strerror(errno)); - return errno; - }; - - rc = write(fd, &val, sizeof(val)); - if (rc < 0) { - g_print("ERROR HostControl: cfam write failed: %s\n", - strerror(errno)); - return errno; - } - - return 0; + g_assert(gpio != NULL); + int i = 0; + int r = GPIO_OK; + for (i = 0; i < num_clks; i++) + { + if (gpio_write(gpio, 0) == -1) + { + r = GPIO_WRITE_ERROR; + break; + } + if (gpio_write(gpio, 1) == -1) + { + r = GPIO_WRITE_ERROR; + break; + } + } + + return r; } -static int fsi_rescan(void) +int +fsi_bitbang(const char* pattern) { - char *one = "1"; - int fd, rc; - - fd = open(FSI_SCAN_PATH, O_WRONLY); - if (fd < 0) { - g_print("ERROR HostControl: Failed to open path '%s': %s\n", - FSI_SCAN_PATH, strerror(errno)); - return errno; - } - rc = write(fd, one, sizeof(one)); - close(fd); - if (rc < 0) { - g_print("ERROR HostControl: Failed to perform FSI scan: %s\n", - strerror(errno)); - return errno; + int rc=GPIO_OK; + int i; + for(i=0;iname = g_strdup("FSI_DATA"); // GPIO struct has non-const char pointer + fsi_clk = malloc(sizeof(GPIO)); + fsi_clk->name = g_strdup("FSI_CLK"); + fsi_enable = malloc(sizeof(GPIO)); + fsi_enable->name = g_strdup("FSI_ENABLE"); + cronus_sel = malloc(sizeof(GPIO)); + cronus_sel->name = g_strdup("CRONUS_SEL"); + + // WARNING: This portion of the hardcode is usable only with VESNIN. + // For the upstream, it should be rewritten for reading this data from the + // JSON file. + num_optionals = 1; + optionals = malloc(sizeof(GPIO)); + optionals->name = g_strdup("CP0_FSI0_DATA_EN"); + optional_pols = malloc(sizeof(gboolean)); + optional_pols[0] = TRUE; + + gpio_get_params(fsi_data); + gpio_get_params(fsi_clk); + gpio_get_params(fsi_enable); + gpio_get_params(cronus_sel); + for (int i = 0; i < num_optionals; ++i) { + gpio_get_params(&optionals[i]); + } } static void -- 2.20.1