mail.coreboot.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
List overview
Download
coreboot-gerrit
February 2018
----- 2025 -----
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
coreboot-gerrit@coreboot.org
1 participants
1573 discussions
Start a n
N
ew thread
Change in coreboot[master]: soc/cavium: Add GPIO driver
by build bot (Jenkins) (Code Review)
14 Feb '18
14 Feb '18
build bot (Jenkins) has posted comments on this change. (
https://review.coreboot.org/23753
) Change subject: soc/cavium: Add GPIO driver ...................................................................... Patch Set 1: Verified-1 Build Failed
https://qa.coreboot.org/job/coreboot-gerrit/67458/
: FAILURE
https://qa.coreboot.org/job/coreboot-checkpatch/21995/
: SUCCESS -- To view, visit
https://review.coreboot.org/23753
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: comment Gerrit-Change-Id: I77b83eaebc94b1e311e6834658074c2c7c5faf55 Gerrit-Change-Number: 23753 Gerrit-PatchSet: 1 Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com> Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org> Gerrit-Comment-Date: Wed, 14 Feb 2018 14:30:40 +0000 Gerrit-HasComments: No Gerrit-HasLabels: Yes
1
0
0
0
Change in coreboot[master]: soc/cavium: Clear LMC interrupt bits after CAR setup
by build bot (Jenkins) (Code Review)
14 Feb '18
14 Feb '18
build bot (Jenkins) has posted comments on this change. (
https://review.coreboot.org/23755
) Change subject: soc/cavium: Clear LMC interrupt bits after CAR setup ...................................................................... Patch Set 1: Verified-1 Build Failed
https://qa.coreboot.org/job/coreboot-gerrit/67460/
: FAILURE
https://qa.coreboot.org/job/coreboot-checkpatch/21996/
: SUCCESS -- To view, visit
https://review.coreboot.org/23755
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: comment Gerrit-Change-Id: I7b71eace5acb47eb42171cc4bfaf6fc1ff01df1c Gerrit-Change-Number: 23755 Gerrit-PatchSet: 1 Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com> Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org> Gerrit-Comment-Date: Wed, 14 Feb 2018 14:30:35 +0000 Gerrit-HasComments: No Gerrit-HasLabels: Yes
1
0
0
0
Change in coreboot[master]: soc/cavium: Implement common clock system
by build bot (Jenkins) (Code Review)
14 Feb '18
14 Feb '18
build bot (Jenkins) has posted comments on this change. (
https://review.coreboot.org/23752
) Change subject: soc/cavium: Implement common clock system ...................................................................... Patch Set 1: Verified-1 Build Failed
https://qa.coreboot.org/job/coreboot-gerrit/67456/
: FAILURE
https://qa.coreboot.org/job/coreboot-checkpatch/21994/
: SUCCESS -- To view, visit
https://review.coreboot.org/23752
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: comment Gerrit-Change-Id: Ifc4fdbaeec78e2fbc956b4821730f2c16f779b91 Gerrit-Change-Number: 23752 Gerrit-PatchSet: 1 Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com> Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org> Gerrit-Comment-Date: Wed, 14 Feb 2018 14:30:05 +0000 Gerrit-HasComments: No Gerrit-HasLabels: Yes
1
0
0
0
Change in coreboot[master]: soc/cavium: Add twsi
by build bot (Jenkins) (Code Review)
14 Feb '18
14 Feb '18
build bot (Jenkins) has posted comments on this change. (
https://review.coreboot.org/23751
) Change subject: soc/cavium: Add twsi ...................................................................... Patch Set 1: Verified-1 Build Failed
https://qa.coreboot.org/job/coreboot-gerrit/67457/
: FAILURE
https://qa.coreboot.org/job/coreboot-checkpatch/21993/
: SUCCESS -- To view, visit
https://review.coreboot.org/23751
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: comment Gerrit-Change-Id: I9f85d024b3ffd0a0c4376a8880d14db9e3570d79 Gerrit-Change-Number: 23751 Gerrit-PatchSet: 1 Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com> Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org> Gerrit-Comment-Date: Wed, 14 Feb 2018 14:29:51 +0000 Gerrit-HasComments: No Gerrit-HasLabels: Yes
1
0
0
0
Change in coreboot[master]: soc/cavium: Clear LMC interrupt bits after CAR setup
by Patrick Rudolph (Code Review)
14 Feb '18
14 Feb '18
Patrick Rudolph has uploaded this change for review. (
https://review.coreboot.org/23755
Change subject: soc/cavium: Clear LMC interrupt bits after CAR setup ...................................................................... soc/cavium: Clear LMC interrupt bits after CAR setup Change-Id: I7b71eace5acb47eb42171cc4bfaf6fc1ff01df1c Signed-off-by: Patrick Rudolph <patrick.rudolph(a)9elements.com> --- M src/soc/cavium/cn81xx/bootblock.c M src/soc/cavium/cn81xx/bootblock_custom.S 2 files changed, 17 insertions(+), 22 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/23755/1 diff --git a/src/soc/cavium/cn81xx/bootblock.c b/src/soc/cavium/cn81xx/bootblock.c index 9517fb7..2be7b6b 100644 --- a/src/soc/cavium/cn81xx/bootblock.c +++ b/src/soc/cavium/cn81xx/bootblock.c @@ -93,33 +93,11 @@ void bootblock_soc_early_init(void) { - /* FIXME: will cache_sync_instructions() do? */ - //cache_sync_instructions(); - - /* The above locking will cause L2 to load zeros without DRAM setup. - This will cause L2C_TADX_INT[rddislmc]. - FIXME: Do we care? See bdk-init.c for reference code if so. - */ } void bootblock_soc_init(void) { -#if 0 - BDK_CSR_DEFINE(l2c_tadx_int, BDK_L2C_TADX_INT_W1C(0)); - l2c_tadx_int.u = 0; - l2c_tadx_int.s.wrdislmc = 1; - l2c_tadx_int.s.rddislmc = 1; - l2c_tadx_int.s.rdnxm = 1; - - BDK_CSR_WRITE(node, BDK_L2C_TADX_INT_W1C(0), l2c_tadx_int.u); -#endif - struct cn81xx_l2c_tad *tad = (struct cn81xx_l2c_tad *)L2C_TAD0_PF_BAR0; - write64(&tad->int_w1c, L2C_TAD_INT_W1C_WRDISLMC | - L2C_TAD_INT_W1C_RDDISLMC | L2C_TAD_INT_W1C_RDNXM); - - /* FIXME: additional locking steps required for CN88xx and CN83xx */ - /* initialize system registers */ init_sysreg(); diff --git a/src/soc/cavium/cn81xx/bootblock_custom.S b/src/soc/cavium/cn81xx/bootblock_custom.S index 00a6aff..fab2e43 100644 --- a/src/soc/cavium/cn81xx/bootblock_custom.S +++ b/src/soc/cavium/cn81xx/bootblock_custom.S @@ -227,6 +227,23 @@ b.gt dirty_cache_line /* Repeat if length is still positive */ dmb sy +clear_interrupts: + /** + * As the memory controller isn't running, but we access the DRAM's + * address space, some interrupt flags had been set. + * Tidy up our mess now on (valid for CN81XX only). + */ + #define L2C_TAD0_INT_W1C 0x87e050040000ULL + mov x0, (L2C_TAD0_INT_W1C >> 32) + lsl x0, x0, 32 + mov x1, (L2C_TAD0_INT_W1C & 0xffffffff) + orr x0, x0, x1 + #undef L2C_TAD0_INT_W1C + + ldr x1, [x0] + orr x1, x1, 0x1c00 /* Clear WRDISLMC, RDDISLMC, RDNXM */ + str x1, [x0] + ret ENDPROC(_setup_car) -- To view, visit
https://review.coreboot.org/23755
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: I7b71eace5acb47eb42171cc4bfaf6fc1ff01df1c Gerrit-Change-Number: 23755 Gerrit-PatchSet: 1 Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com>
1
0
0
0
Change in coreboot[master]: soc/cavium: Only enable CAR if DRAM PLL isn't running
by Patrick Rudolph (Code Review)
14 Feb '18
14 Feb '18
Patrick Rudolph has uploaded this change for review. (
https://review.coreboot.org/23754
Change subject: soc/cavium: Only enable CAR if DRAM PLL isn't running ...................................................................... soc/cavium: Only enable CAR if DRAM PLL isn't running Change-Id: I76f1a44c215f933af74f4d659de59013f2677dad --- M src/soc/cavium/cn81xx/bootblock.c M src/soc/cavium/cn81xx/bootblock_custom.S 2 files changed, 16 insertions(+), 16 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/54/23754/1 diff --git a/src/soc/cavium/cn81xx/bootblock.c b/src/soc/cavium/cn81xx/bootblock.c index ea83369..9517fb7 100644 --- a/src/soc/cavium/cn81xx/bootblock.c +++ b/src/soc/cavium/cn81xx/bootblock.c @@ -26,19 +26,6 @@ #include <program_loading.h> #include <timestamp.h> -static int is_dram_enabled(void) -{ -#if 0 - BDK_CSR_INIT(lmcx_ddr_pll_ctl, node, BDK_LMCX_DDR_PLL_CTL(0)); - if (CAVIUM_IS_MODEL(CAVIUM_CN8XXX)) - return lmcx_ddr_pll_ctl.cn83xx.reset_n; - else - return !lmcx_ddr_pll_ctl.cn9.pll_reset; -#endif - /* FIXME: stub - see __bdk_is_dram_enabled for reference code */ - return 0; -} - static void init_sysreg(void) { #if 0 @@ -105,9 +92,6 @@ void bootblock_soc_early_init(void) { - /* Only lock L2 if DDR3 isn't initialized */ - if (is_dram_enabled()) - return; /* FIXME: will cache_sync_instructions() do? */ //cache_sync_instructions(); diff --git a/src/soc/cavium/cn81xx/bootblock_custom.S b/src/soc/cavium/cn81xx/bootblock_custom.S index d3eae1d..00a6aff 100644 --- a/src/soc/cavium/cn81xx/bootblock_custom.S +++ b/src/soc/cavium/cn81xx/bootblock_custom.S @@ -50,6 +50,22 @@ #error Unknown endianness #endif + #define BDK_LMCX 0x87e088000000ULL + #define DDR_PLL_CTL0 0x258 + mov x0, (BDK_LMCX >> 32) + lsl x0, x0, 32 + mov x1, (BDK_LMCX & 0xffffffff) + orr x0, x0, x1 + + /* Test if DRAM PLL is running */ + ldr x1, [x0, DDR_PLL_CTL0] + + tst x1, 0x80 + #undef BDK_LMCX + #undef DDR_PLL_CTL0 + + b.ne cache_setup_done + bl _setup_car cache_setup_done: -- To view, visit
https://review.coreboot.org/23754
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: I76f1a44c215f933af74f4d659de59013f2677dad Gerrit-Change-Number: 23754 Gerrit-PatchSet: 1 Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com>
1
0
0
0
Change in coreboot[master]: soc/cavium: Add GPIO driver
by Patrick Rudolph (Code Review)
14 Feb '18
14 Feb '18
Patrick Rudolph has uploaded this change for review. (
https://review.coreboot.org/23753
Change subject: soc/cavium: Add GPIO driver ...................................................................... soc/cavium: Add GPIO driver Change-Id: I77b83eaebc94b1e311e6834658074c2c7c5faf55 Signed-off-by: Patrick Rudolph <patrick.rudolph(a)9elements.com> --- M src/soc/cavium/cn81xx/Makefile.inc M src/soc/cavium/common/Makefile.inc M src/soc/cavium/common/gpio.c M src/soc/cavium/common/include/soc/gpio.h 4 files changed, 169 insertions(+), 174 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/53/23753/1 diff --git a/src/soc/cavium/cn81xx/Makefile.inc b/src/soc/cavium/cn81xx/Makefile.inc index 8fe8f44..6c129e8 100644 --- a/src/soc/cavium/cn81xx/Makefile.inc +++ b/src/soc/cavium/cn81xx/Makefile.inc @@ -70,7 +70,6 @@ romstage-y += ../common/lame_string.c - #verstage-y += ../common/cbmem.c #verstage-y += ../common/gpio.c #verstage-y += gpio.c diff --git a/src/soc/cavium/common/Makefile.inc b/src/soc/cavium/common/Makefile.inc index 48cc7bd..f51e13e 100644 --- a/src/soc/cavium/common/Makefile.inc +++ b/src/soc/cavium/common/Makefile.inc @@ -18,16 +18,19 @@ bootblock-$(CONFIG_BOOTBLOCK_CUSTOM) += bootblock.c bootblock-y += twsi.c bootblock-y += clock.c +bootblock-y += gpio.c romstage-y += twsi.c romstage-y += clock.c +romstage-y += gpio.c ramstage-y += twsi.c ramstage-y += clock.c +ramstage-y += gpio.c CPPFLAGS_common += -Isrc/soc/cavium/common/include diff --git a/src/soc/cavium/common/gpio.c b/src/soc/cavium/common/gpio.c index add2100..b7620e5 100644 --- a/src/soc/cavium/common/gpio.c +++ b/src/soc/cavium/common/gpio.c @@ -1,138 +1,183 @@ /* - * This file is part of the coreboot project. + * Copyright 2018-present Facebook, Inc. * - * Copyright 2017-present Facebook, 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; version 2 of the License. - * - * 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. + * SPDX-License-Identifier: GPL-2.0+ */ -/* FIXME: scaffolding based on rk3399 */ - -#include <arch/io.h> -#include <assert.h> #include <console/console.h> -#include <gpio.h> #include <soc/gpio.h> -//#include <soc/grf.h> -#include <soc/soc.h> -#include <stdlib.h> +#include <arch/io.h> +#include <endian.h> -static void gpio_set_dir(gpio_t gpio, enum gpio_dir dir) +union gpio_const { + u64 u; + struct { + u64 gpios:8; /** Number of GPIOs implemented */ + u64 pp:8; /** Number of PP vectors */ + u64:48; /* Reserved */ + } s; +}; +union bit_cfg { + u64 u; + struct { + u64 tx_oe : 1; /* Output Enable */ + u64 xor : 1; /* Invert */ + u64 int_en : 1; /* Interrupt Enable */ + u64 int_type : 1; /* Type of Interrupt */ + u64 filt_cnt : 4; /* Glitch filter counter */ + u64 filt_sel : 4; /* Glitch filter select */ + u64 tx_od : 1; /* Set Output to Open Drain */ + u64 : 3; + u64 pin_sel : 10; /* Select type of pin */ + u64 : 38; + } s; +}; + +struct cavium_gpio { + u64 rx_dat; + u64 tx_set; + u64 tx_clr; + u64 multicast; + u64 ocla_exten_trg; + u64 strap; + u64 reserved[12]; + union gpio_const gpio_const; /* Offset 90 */ + u64 reserved2[109]; + union bit_cfg bit_cfg[48]; /* Offset 400 */ +}; + +/* Base address of GPIO BAR */ +static void *gpio_get_baseaddr(void) { -#if 0 - clrsetbits_le32(&gpio_port[gpio.port]->swporta_ddr, - 1 << gpio.num, dir << gpio.num); -#endif + return (void *)0x803000000000ULL; } -static void gpio_set_pull(gpio_t gpio, enum gpio_pull pull) +/* Number of GPIO pins. Usually 48. */ +gpio_t gpio_pin_count(void) { -#if 0 - u32 pull_val = gpio_get_pull_val(gpio, pull); - if (is_pmu_gpio(gpio) && IS_ENABLED(CONFIG_SOC_ROCKCHIP_RK3288)) - clrsetbits_le32(gpio_grf_reg(gpio), 3 << (gpio.idx * 2), - pull_val << (gpio.idx * 2)); - else - write32(gpio_grf_reg(gpio), RK_CLRSETBITS(3 << (gpio.idx * 2), - pull_val << (gpio.idx * 2))); -#endif + struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr(); + union gpio_const gpio_const; + + gpio_const.u = read64(®s->gpio_const.u); + + if (gpio_const.s.gpios > 64) + return 64; // FIXME: Add support for more than 64 GPIOs + return gpio_const.s.gpios; } +/* Set GPIO to software control and direction INPUT */ void gpio_input(gpio_t gpio) { -#if 0 - gpio_set_pull(gpio, GPIO_PULLNONE); - gpio_set_dir(gpio, GPIO_INPUT); -#endif + struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr(); + union bit_cfg bit_cfg; + + if (gpio >= gpio_pin_count()) + return; + + printk(BIOS_SPEW, "GPIO(%u): direction input\n", gpio); + + bit_cfg.u = read64(®s->bit_cfg[gpio]); + bit_cfg.s.pin_sel = 0; + bit_cfg.s.tx_oe = 0; + write64(®s->bit_cfg[gpio], bit_cfg.u); +} + +/* Set GPIO of direction OUTPUT to level */ +void gpio_set(gpio_t gpio, int value) +{ + struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr(); + + if (gpio >= gpio_pin_count()) + return; + + printk(BIOS_SPEW, "GPIO(%u): level: %u\n", gpio, !!value); + + if (value) + write64(®s->tx_set, 1 << gpio); + else + write64(®s->tx_clr, 1 << gpio); +} + +/* Set GPIO direction to OUTPUT with level */ +void gpio_output(gpio_t gpio, int value) +{ + struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr(); + union bit_cfg bit_cfg; + + if (gpio >= gpio_pin_count()) + return; + + gpio_set(gpio, value); + + printk(BIOS_SPEW, "GPIO(%u): direction output with level: %u\n", gpio, + !!value); + + bit_cfg.u = read64(®s->bit_cfg[gpio]); + bit_cfg.s.pin_sel = 0; + bit_cfg.s.tx_oe = 1; + write64(®s->bit_cfg[gpio], bit_cfg.u); +} + +/* Set GPIO invert flag, that affects INPUT and OUTPUT */ +void gpio_invert(gpio_t gpio, int value) +{ + struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr(); + union bit_cfg bit_cfg; + + if (gpio >= gpio_pin_count()) + return; + + bit_cfg.u = read64(®s->bit_cfg[gpio]); + bit_cfg.s.xor = !!value; + write64(®s->bit_cfg[gpio], bit_cfg.u); + + printk(BIOS_SPEW, "GPIO(%u): invert: %s\n", gpio, value ? "ON" : "OFF"); +} + +/* Read GPIO level with direction set to INPUT */ +int gpio_get(gpio_t gpio) +{ + struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr(); + + if (gpio >= gpio_pin_count()) + return 0; + + const u64 reg = read64(®s->rx_dat); + printk(BIOS_SPEW, "GPIO(%u): input: %u\n", gpio, !!(reg & (1 << gpio))); + + return !!(reg & (1 << gpio)); +} + +/* Read GPIO STRAP level sampled at cold boot */ +int gpio_strap_value(gpio_t gpio) +{ + struct cavium_gpio *regs = (struct cavium_gpio *)gpio_get_baseaddr(); + + if (gpio >= gpio_pin_count()) + return 0; + + const u64 reg = read64(®s->strap); + printk(BIOS_SPEW, "GPIO(%u): strap: %u\n", gpio, !!(reg & (1 << gpio))); + + return !!(reg & (1 << gpio)); +} + +/* FIXME: Parse devicetree ? */ +void gpio_init(void) +{ + const size_t pin_count = gpio_pin_count(); + + printk(BIOS_DEBUG, "GPIO: base address: %p, pin count: %d\n", + gpio_get_baseaddr(), pin_count); + + if (!pin_count) + return; } void gpio_input_pulldown(gpio_t gpio) { -#if 0 - gpio_set_pull(gpio, GPIO_PULLDOWN); - gpio_set_dir(gpio, GPIO_INPUT); -#endif } void gpio_input_pullup(gpio_t gpio) { -#if 0 - gpio_set_pull(gpio, GPIO_PULLUP); - gpio_set_dir(gpio, GPIO_INPUT); -#endif -} - -void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, enum gpio_pull pull) -{ -#if 0 - uint32_t int_polarity, inttype_level; - uint32_t mask = BIT(gpio.num); - - /* gpio pull only PULLNONE, PULLUP, PULLDOWN status */ - assert(pull <= GPIO_PULLDOWN); - - gpio_set_dir(gpio, GPIO_INPUT); - gpio_set_pull(gpio, pull); - - int_polarity = inttype_level = 0; - switch (type) { - case IRQ_TYPE_EDGE_RISING: - int_polarity = mask; - inttype_level = mask; - break; - case IRQ_TYPE_EDGE_FALLING: - inttype_level = mask; - break; - case IRQ_TYPE_LEVEL_HIGH: - int_polarity = mask; - break; - case IRQ_TYPE_LEVEL_LOW: - break; - } - clrsetbits_le32(&gpio_port[gpio.port]->int_polarity, - mask, int_polarity); - clrsetbits_le32(&gpio_port[gpio.port]->inttype_level, - mask, inttype_level); - - setbits_le32(&gpio_port[gpio.port]->inten, mask); - clrbits_le32(&gpio_port[gpio.port]->intmask, mask); -#endif -} - -int gpio_irq_status(gpio_t gpio) -{ -#if 0 - uint32_t mask = BIT(gpio.num); - uint32_t int_status = read32(&gpio_port[gpio.port]->int_status); - - if (!(int_status & mask)) - return 0; - - setbits_le32(&gpio_port[gpio.port]->porta_eoi, mask); - return 1; -#endif -} - -int gpio_get(gpio_t gpio) -{ -#if 0 - return (read32(&gpio_port[gpio.port]->ext_porta) >> gpio.num) & 0x1; -#endif -} - -void gpio_output(gpio_t gpio, int value) -{ -#if 0 - clrsetbits_le32(&gpio_port[gpio.port]->swporta_dr, 1 << gpio.num, - !!value << gpio.num); - gpio_set_dir(gpio, GPIO_OUTPUT); - gpio_set_pull(gpio, GPIO_PULLNONE); -#endif } diff --git a/src/soc/cavium/common/include/soc/gpio.h b/src/soc/cavium/common/include/soc/gpio.h index 666f7bb..6986482 100644 --- a/src/soc/cavium/common/include/soc/gpio.h +++ b/src/soc/cavium/common/include/soc/gpio.h @@ -19,68 +19,16 @@ #include <types.h> -typedef union { - u32 raw; -#if 0 - struct { - union { - struct { - u32 num : 5; - u32 reserved1 : 27; - }; - struct { - u32 idx : 3; - u32 bank : 2; - u32 port : 4; - u32 reserved2 : 23; - }; - }; - }; -#endif -} gpio_t; +typedef u32 gpio_t; +#include <gpio.h> -#if 0 -enum { - GPIO_A = 0, - GPIO_B, - GPIO_C, - GPIO_D, -}; +/* The following functions must be implemented by SoC/board code. */ -extern struct rockchip_gpio_regs *gpio_port[]; -/* Check if the gpio port is a pmu gpio */ -int is_pmu_gpio(gpio_t gpio); +gpio_t gpio_pin_count(void); +void gpio_invert(gpio_t gpio, int value); +int gpio_strap_value(gpio_t gpio); -/* Return the io addr of gpio register */ -void *gpio_grf_reg(gpio_t gpio); - -enum gpio_pull { - GPIO_PULLNONE = 0, - GPIO_PULLUP = 1, - GPIO_PULLDOWN = 2, -}; - -enum gpio_dir { - GPIO_INPUT = 0, - GPIO_OUTPUT = 1, -}; - -enum gpio_irq_type { - IRQ_TYPE_EDGE_RISING = 0, - IRQ_TYPE_EDGE_FALLING, - IRQ_TYPE_LEVEL_HIGH, - IRQ_TYPE_LEVEL_LOW, -}; - -/* Setup and enable irq */ -void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, enum gpio_pull pull); - -/* Check and clear irq status */ -int gpio_irq_status(gpio_t gpio); - -/* The gpio pull bias setting may be different between SoCs */ -u32 gpio_get_pull_val(gpio_t gpio, enum gpio_pull pull); -#endif +void gpio_init(void); #endif -- To view, visit
https://review.coreboot.org/23753
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: I77b83eaebc94b1e311e6834658074c2c7c5faf55 Gerrit-Change-Number: 23753 Gerrit-PatchSet: 1 Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com>
1
0
0
0
Change in coreboot[master]: soc/cavium: Implement common clock system
by Patrick Rudolph (Code Review)
14 Feb '18
14 Feb '18
Patrick Rudolph has uploaded this change for review. (
https://review.coreboot.org/23752
Change subject: soc/cavium: Implement common clock system ...................................................................... soc/cavium: Implement common clock system Get rid of cn81xx custom clock code. Fix UART divisor. Change-Id: Ifc4fdbaeec78e2fbc956b4821730f2c16f779b91 Signed-off-by: Patrick Rudolph <patrick.rudolph(a)9elements.com> --- M src/soc/cavium/cn81xx/Makefile.inc D src/soc/cavium/cn81xx/clock.c D src/soc/cavium/cn81xx/include/soc/clock.h M src/soc/cavium/cn81xx/include/soc/soc.h M src/soc/cavium/cn81xx/timer.c M src/soc/cavium/cn81xx/uart.c M src/soc/cavium/common/Makefile.inc A src/soc/cavium/common/clock.c M src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h A src/soc/cavium/common/include/soc/clock.h M src/soc/cavium/common/twsi.c M src/soc/cavium/common/wdt.c 12 files changed, 128 insertions(+), 197 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/52/23752/1 diff --git a/src/soc/cavium/cn81xx/Makefile.inc b/src/soc/cavium/cn81xx/Makefile.inc index fbba930..8fe8f44 100644 --- a/src/soc/cavium/cn81xx/Makefile.inc +++ b/src/soc/cavium/cn81xx/Makefile.inc @@ -26,7 +26,6 @@ #bootblock-y += ../common/gpio.c #bootblock-y += ../common/pwm.c bootblock-y += bootblock.c -bootblock-y += clock.c #bootblock-y += gpio.c bootblock-y += twsi.c bootblock-y += l2c.c @@ -79,7 +78,6 @@ #verstage-y += ../common/i2c.c #verstage-y += spi.c #verstage-$(CONFIG_DRIVERS_UART) += uart.c -#verstage-y += clock.c #verstage-y += timer.c verstage-y += ../common/wdt.c @@ -88,7 +86,6 @@ romstage-y += ../common/cbmem.c romstage-y += spi.c romstage-$(CONFIG_DRIVERS_UART) += uart.c -romstage-y += clock.c romstage-y += mmu_operations.c #romstage-y += ../common/pwm.c romstage-y += timer.c @@ -103,7 +100,6 @@ ramstage-y += spi.c ramstage-y += twsi.c ramstage-$(CONFIG_DRIVERS_UART) += uart.c -##ramstage-y += clock.c #ramstage-y += ../common/gpio.c #ramstage-y += gpio.c #ramstage-y += ../common/i2c.c diff --git a/src/soc/cavium/cn81xx/clock.c b/src/soc/cavium/cn81xx/clock.c deleted file mode 100644 index 0af466c..0000000 --- a/src/soc/cavium/cn81xx/clock.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2017-present Facebook, Inc. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <arch/io.h> -#include <libbdk-hal/bdk-clock.h> -#include <soc/addressmap.h> -#include <soc/clock.h> -#include <soc/soc.h> -#include <soc/timer.h> - -uint64_t clock_get_rate(bdk_clock_t source) -{ - struct cn81xx_rst *rst = (struct cn81xx_rst *)RST_PF_BAR0; - const uint64_t REF_CLOCK = BDK_REF_CLOCK; - - u64 mul = read64(&rst->boot); - - switch (source) { - case BDK_CLOCK_TIME: - return BDK_GTI_RATE; /* Programed as part of setup */ - case BDK_CLOCK_MAIN_REF: - return REF_CLOCK; - case BDK_CLOCK_RCLK: - mul = (mul >> RST_BOOT_C_MUL_SHIFT) & RST_BOOT_C_MUL_MASK; - return REF_CLOCK * mul; - case BDK_CLOCK_SCLK: - mul = (mul >> RST_BOOT_PNR_MUL_SHIFT) & RST_BOOT_PNR_MUL_MASK; - return REF_CLOCK * mul; - } - - return 0; -} diff --git a/src/soc/cavium/cn81xx/include/soc/clock.h b/src/soc/cavium/cn81xx/include/soc/clock.h deleted file mode 100644 index ad535e0..0000000 --- a/src/soc/cavium/cn81xx/include/soc/clock.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (c) 2003-2017 Cavium Inc. (support(a)cavium.com). All rights - * reserved. - * Copyright 2017-present Facebook, Inc. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __SOC_CAVIUM_CN81XX_CLOCK_H__ -#define __SOC_CAVIUM_CN81XX_CLOCK_H__ - -#include <commonlib/helpers.h> -#include <libbdk-arch/bdk-numa.h> -#include <libbdk-hal/bdk-clock.h> -#include <soc/addressmap.h> -#include <types.h> - -#if 0 -enum cn81xx_clock_source { - BDK_CLOCK_TIME, /* Clock for telling time with fast access. Uses GTI in core */ - BDK_CLOCK_MAIN_REF, /* Main reference clock */ - BDK_CLOCK_RCLK, /* Clock used by cores, coherent bus and L2 cache. */ - BDK_CLOCK_SCLK, /* Clock used by IO blocks. */ -}; -#endif - -#define BDK_REF_CLOCK 50000000ULL - -#if 0 -uint64_t clock_get_rate(enum cn81xx_clock_source); -static inline uint64_t bdk_clock_get_rate(bdk_node_t node, enum cn81xx_clock_source clock) -{ - return clock_get_rate((enum cn81xx_clock_source)clock); -} -#endif -/* FIXME(dhendrix): ...and later moved into bdk-clock.h... */ -#if 0 -uint64_t clock_get_rate(bdk_clock_t clock); -static inline uint64_t clock_get_rate_slow(bdk_clock_t clock) -{ - clock_get_rate(clock); -} -#endif - -#endif /* __SOC_CAVIUM_CN81XX_CLOCK_H__ */ diff --git a/src/soc/cavium/cn81xx/include/soc/soc.h b/src/soc/cavium/cn81xx/include/soc/soc.h index d1f200b..a751e64 100644 --- a/src/soc/cavium/cn81xx/include/soc/soc.h +++ b/src/soc/cavium/cn81xx/include/soc/soc.h @@ -19,72 +19,6 @@ #include <inttypes.h> #include <types.h> -/* RST registers */ -struct cn81xx_rst { - u64 boot; - u64 delay; - u64 cfg; - u64 ocx; - u8 rsvd1[0x8]; - u64 intr; - u64 intr_w1s; - u64 ckill; - u64 ctl0; - u64 ctl1; - u64 ctl2; - u8 rsvd2[0x28]; - u64 soft_rst; - u64 out_ctl; - u64 thermal_alert; - u8 rsvd3[0x8]; - u64 int_ena_w1s; - u64 int_ena_w1c; - u8 rsvd4[0x10]; - u64 soft_prst0; - u64 soft_prst1; - u64 soft_prst2; - u8 rsvd5[0x28]; - u64 pp_power; - u64 power_dbg; - u64 pp_power_stat; - u8 rsvd6[0x20]; - u64 pp_available; - u64 pp_reset; - u64 pp_pending; - u8 rsvd7[0x8]; - u64 ref_cntr; - u8 rsvd8[0x50]; - u64 debug; - u8 rsvd9[0x8]; - u64 cold_data0; - u64 cold_data1; - u64 cold_data2; - u64 cold_data3; - u64 cold_data4; - u64 cold_data5; -}; -check_member(cn81xx_rst, cold_data5, 0x17e8 - 0x1600); - -#define RST_BOOT_RBOOT_PIN (1 << 0) -#define RST_BOOT_RBOOT (1 << 1) -#define RST_BOOT_LBOOT_SHIFT 2 -#define RST_BOOT_LBOOT_MASK 0x3ff -#define RST_BOOT_LBOOT_EXT23_SHIFT 12 -#define RST_BOOT_LBOOT_EXT23_MASK 0x3f -#define RST_BOOT_LBOOT_JTG (1 << 24) -#define RST_BOOT_LBOOT_CKILL (1 << 25) -#define RST_BOOT_PNR_MUL_SHIFT 33 -#define RST_BOOT_PNR_MUL_MASK 0x3f -#define RST_BOOT_C_MUL_SHIFT 40 -#define RST_BOOT_C_MUL_MASK 0x7f -#define RST_BOOT_DIS_SCAN (1 << 55) -#define RST_BOOT_DIS_HUK (1 << 56) -#define RST_BOOT_JT_TSTMODE (1 << 58) -#define RST_BOOT_CKILL_PPDIS (1 << 59) -#define RST_BOOT_TRUSTED_MODE (1 << 60) -#define RST_BOOT_JTCSRDIS (1 << 62) -#define RST_BOOT_CHIPKILL (1 << 63) - /* MIO BOOT Registers */ struct cn81xx_mio_boot { u8 rsvd0[0xb0]; diff --git a/src/soc/cavium/cn81xx/timer.c b/src/soc/cavium/cn81xx/timer.c index 3d59a40..a60d5cb 100644 --- a/src/soc/cavium/cn81xx/timer.c +++ b/src/soc/cavium/cn81xx/timer.c @@ -39,7 +39,7 @@ return; /* Configure GTI to tick at BDK_GTI_RATE */ - u64 sclk = clock_get_rate(BDK_CLOCK_SCLK); + u64 sclk = thunderx_get_io_clock(); #if 0 /* * FIXME(dhendrix): Had difficulty using reference code's way of @@ -58,7 +58,7 @@ read32(>i->cc_cntcr); /* FIXME: is this needed? */ /* Enable the core timer */ - BDK_MSR(CNTFRQ_EL0, BDK_GTI_RATE); /* Needed for Asim (FIXME: not needed for HW?) */ + BDK_MSR(CNTFRQ_EL0, 100000000ull); /* Needed for Asim (FIXME: not needed for HW?) */ #if 0 bdk_ap_cntps_ctl_el1_t cntps_ctl_el1; cntps_ctl_el1.u = 0; diff --git a/src/soc/cavium/cn81xx/uart.c b/src/soc/cavium/cn81xx/uart.c index b4759aa..aacca82 100644 --- a/src/soc/cavium/cn81xx/uart.c +++ b/src/soc/cavium/cn81xx/uart.c @@ -15,11 +15,22 @@ #include <stdint.h> #include <soc/clock.h> #include <soc/uart.h> +#include <assert.h> + +#define UART_SCLK_DIV 3 + +static size_t uart_sclk_divisor(size_t reg) +{ + static const u8 div[] = {1, 2, 4, 6, 8, 16, 24, 32}; + + assert(reg < ARRAY_SIZE(div)); + + return div[reg]; +} unsigned int uart_platform_refclk(void) { - /* FIXME: this probably isn't right */ - return BDK_REF_CLOCK; + return thunderx_get_io_clock() / uart_sclk_divisor(UART_SCLK_DIV); } uintptr_t uart_platform_base(int idx) @@ -45,7 +56,7 @@ c. Deassert the HCLK clock divider reset: UCTL_CTL[H_CLKDIV_RST] = 0. */ clrsetbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLKDIV_MASK << UART_UCTL_CTL_H_CLKDIV_SEL_SHIFT, - 3 << UART_UCTL_CTL_H_CLKDIV_SEL_SHIFT); + UART_SCLK_DIV << UART_UCTL_CTL_H_CLKDIV_SEL_SHIFT); clrbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLK_BYP_SEL); setbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLK_EN); clrbits_le64(&uart->uctl_ctl, UART_UCTL_CTL_H_CLKDIV_RST); @@ -78,7 +89,8 @@ This means BRDI = 1 and BRDF = 0.085. Therefore, fractional part, BRDF = integer((0.085x64)+0.5) = 5 Generated baud rate divider = 1+5/64 = 1.078 */ - u64 divisor = clock_get_rate(BDK_CLOCK_SCLK) / (baudrate * 16 * 6 / 64); + u64 divisor = thunderx_get_io_clock() / + (baudrate * 16 * uart_sclk_divisor(UART_SCLK_DIV) / 64); write32(&uart->pl011.ibrd, divisor >> 6); write32(&uart->pl011.fbrd, divisor & UART_FBRD_BAUD_DIVFRAC_MASK); diff --git a/src/soc/cavium/common/Makefile.inc b/src/soc/cavium/common/Makefile.inc index 6777dfc..48cc7bd 100644 --- a/src/soc/cavium/common/Makefile.inc +++ b/src/soc/cavium/common/Makefile.inc @@ -17,13 +17,17 @@ bootblock-$(CONFIG_BOOTBLOCK_CUSTOM) += bootblock.c bootblock-y += twsi.c +bootblock-y += clock.c romstage-y += twsi.c +romstage-y += clock.c + ramstage-y += twsi.c +ramstage-y += clock.c CPPFLAGS_common += -Isrc/soc/cavium/common/include diff --git a/src/soc/cavium/common/clock.c b/src/soc/cavium/common/clock.c new file mode 100644 index 0000000..1a5664d --- /dev/null +++ b/src/soc/cavium/common/clock.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2016, Cavium, Inc. <support(a)cavium.com> + * Aaron Williams, <aaron.williams(a)cavium.com> + * Copyright 2018-present Facebook, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <soc/clock.h> +#include <arch/io.h> + +#define RST_BOOT ((void *const)0x87e006001600ll) +#define PLL_REF_CLK 50000000 /* 50 MHz */ + +union cavm_rst_boot { + u64 u; + struct { + u64 rboot_pin:1; + u64 rboot:1; + u64 lboot:10; + u64 lboot_ext23:6; + u64 lboot_ext45:6; + u64 reserved_24_29:6; + u64 lboot_oci:3; + u64 pnr_mul:6; + u64 reserved_39_39:1; + u64 c_mul:7; + u64 reserved_47_54:8; + u64 dis_scan:1; + u64 dis_huk:1; + u64 vrm_err:1; + u64 jt_tstmode:1; + u64 ckill_ppdis:1; + u64 trusted_mode:1; + u64 ejtagdis:1; + u64 jtcsrdis:1; + u64 chipkill:1; + } s; +}; + +/** + * Returns the reference clock speed in Hz + */ +u64 thunderx_get_ref_clock(void) +{ + return PLL_REF_CLK; +} + + +/** + * Returns the I/O clock speed in Hz + */ +u64 thunderx_get_io_clock(void) +{ + union cavm_rst_boot rst_boot; + + rst_boot.u = read64(RST_BOOT); + + return rst_boot.s.pnr_mul * PLL_REF_CLK; +} + +/** + * Returns the core clock speed in Hz + */ +u64 thunderx_get_core_clock(void) +{ + union cavm_rst_boot rst_boot; + + rst_boot.u = read64(RST_BOOT); + + return rst_boot.s.c_mul * PLL_REF_CLK; +} diff --git a/src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h b/src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h index ce02223..9a22fde 100644 --- a/src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h +++ b/src/soc/cavium/common/include/soc/bdk/libbdk-hal/bdk-clock.h @@ -42,6 +42,9 @@ /* FIXME(dhendrix): added */ #include <libbdk-arch/bdk-asm.h> #include <libbdk-arch/bdk-numa.h> +/* FIXME(prudolph): added */ + +#include <soc/clock.h> /** * @file @@ -66,10 +69,21 @@ BDK_CLOCK_SCLK, /**< Clock used by IO blocks. */ } bdk_clock_t; -uint64_t clock_get_rate(bdk_clock_t clock); static inline uint64_t clock_get_rate_slow(bdk_clock_t clock) { - clock_get_rate(clock); + const uint64_t REF_CLOCK = 50000000; + + switch (clock) { + case BDK_CLOCK_TIME: + return BDK_GTI_RATE; /* Programed as part of setup */ + case BDK_CLOCK_MAIN_REF: + return REF_CLOCK; + case BDK_CLOCK_RCLK: + return thunderx_get_core_clock(); + case BDK_CLOCK_SCLK: + return thunderx_get_io_clock(); + } + return 0; } /** diff --git a/src/soc/cavium/common/include/soc/clock.h b/src/soc/cavium/common/include/soc/clock.h new file mode 100644 index 0000000..78025dc --- /dev/null +++ b/src/soc/cavium/common/include/soc/clock.h @@ -0,0 +1,15 @@ +/* + * Copyright 2018-present Facebook, Inc. + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef SRC_SOC_CAVIUM_CN81XX_INCLUDE_CLOCK_H_ +#define SRC_SOC_CAVIUM_CN81XX_INCLUDE_CLOCK_H_ + +#include <types.h> + +u64 thunderx_get_ref_clock(void); +u64 thunderx_get_io_clock(void); +u64 thunderx_get_core_clock(void); + +#endif /* SRC_SOC_CAVIUM_CN81XX_INCLUDE_CLOCK_H_ */ diff --git a/src/soc/cavium/common/twsi.c b/src/soc/cavium/common/twsi.c index e2ea838..d9fd3fb 100644 --- a/src/soc/cavium/common/twsi.c +++ b/src/soc/cavium/common/twsi.c @@ -6,16 +6,13 @@ #include <console/console.h> #include <soc/twsi.h> +#include <soc/clock.h> #include <device/i2c.h> #include <device/i2c_simple.h> #include <assert.h> #include <delay.h> #include <arch/io.h> - -#define RST_BOOT ((void *const)0x87e006001600ll) -#define PLL_REF_CLK 50000000 /* 50 MHz */ - #define TWSI_THP 24 #define TWSI_SW_TWSI 0x1000 @@ -23,32 +20,6 @@ #define TWSI_INT 0x1010 #define TWSI_SW_TWSI_EXT 0x1018 -union rst_boot { - u64 u; - struct { - u64 rboot_pin:1; - u64 rboot:1; - u64 lboot:10; - u64 lboot_ext23:6; - u64 lboot_ext45:6; - u64 reserved_24_29:6; - u64 lboot_oci:3; - u64 pnr_mul:6; - u64 reserved_39_39:1; - u64 c_mul:7; - u64 reserved_47_54:8; - u64 dis_scan:1; - u64 dis_huk:1; - u64 vrm_err:1; - u64 jt_tstmode:1; - u64 ckill_ppdis:1; - u64 trusted_mode:1; - u64 ejtagdis:1; - u64 jtcsrdis:1; - u64 chipkill:1; - } s; -}; - union twsx_sw_twsi { u64 u; struct { @@ -636,16 +607,14 @@ static int twsi_set_speed(void *baseaddr, const unsigned int speed) { - int io_clock_hz; + u64 io_clock_hz; int n_div; int m_div; union twsx_sw_twsi sw_twsi; - union rst_boot rst_boot; printk(BIOS_DEBUG, "%s(%p, %u)\n", __func__, baseaddr, speed); - rst_boot.u = read64(RST_BOOT); - io_clock_hz = rst_boot.s.pnr_mul * PLL_REF_CLK; + io_clock_hz = thunderx_get_io_clock(); /* Set the TWSI clock to a conservative TWSI_BUS_FREQ. Compute the * clocks M divider based on the SCLK. diff --git a/src/soc/cavium/common/wdt.c b/src/soc/cavium/common/wdt.c index 514a304..9b0f28f 100644 --- a/src/soc/cavium/common/wdt.c +++ b/src/soc/cavium/common/wdt.c @@ -29,7 +29,7 @@ */ void watchdog_set(unsigned int timeout_ms) { - uint64_t sclk = clock_get_rate(BDK_CLOCK_SCLK); + uint64_t sclk = thunderx_get_io_clock(); uint64_t timeout_sclk = sclk * timeout_ms / 1000; /* Per comment above, we want the watchdog to expire at 3x the rate specified */ timeout_sclk /= 3; -- To view, visit
https://review.coreboot.org/23752
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: Ifc4fdbaeec78e2fbc956b4821730f2c16f779b91 Gerrit-Change-Number: 23752 Gerrit-PatchSet: 1 Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com>
1
0
0
0
Change in coreboot[master]: soc/cavium: Add twsi
by Patrick Rudolph (Code Review)
14 Feb '18
14 Feb '18
Patrick Rudolph has uploaded this change for review. (
https://review.coreboot.org/23751
Change subject: soc/cavium: Add twsi ...................................................................... soc/cavium: Add twsi Add TWSI. Ported from BDK uboot tree. Change-Id: I9f85d024b3ffd0a0c4376a8880d14db9e3570d79 Signed-off-by: Patrick Rudolph <patrick.rudolph(a)9elements.com> --- M src/soc/cavium/cn81xx/Makefile.inc A src/soc/cavium/cn81xx/twsi.c M src/soc/cavium/common/Makefile.inc D src/soc/cavium/common/i2c.c A src/soc/cavium/common/include/soc/twsi.h A src/soc/cavium/common/twsi.c 6 files changed, 764 insertions(+), 331 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/51/23751/1 diff --git a/src/soc/cavium/cn81xx/Makefile.inc b/src/soc/cavium/cn81xx/Makefile.inc index d2bd94b..fbba930 100644 --- a/src/soc/cavium/cn81xx/Makefile.inc +++ b/src/soc/cavium/cn81xx/Makefile.inc @@ -28,12 +28,15 @@ bootblock-y += bootblock.c bootblock-y += clock.c #bootblock-y += gpio.c +bootblock-y += twsi.c bootblock-y += l2c.c bootblock-y += mmu_operations.c #bootblock-y += sdram.c bootblock-y += timer.c bootblock-y += ../common/wdt.c +romstage-y += twsi.c + romstage-y += sdram.c romstage-y += ../common/bdk/libdram/libdram.c romstage-y += ../common/bdk/libbdk-arch/bdk-csr.c @@ -98,6 +101,7 @@ ramstage-y += ../common/cbmem.c ramstage-y += sdram.c ramstage-y += spi.c +ramstage-y += twsi.c ramstage-$(CONFIG_DRIVERS_UART) += uart.c ##ramstage-y += clock.c #ramstage-y += ../common/gpio.c diff --git a/src/soc/cavium/cn81xx/twsi.c b/src/soc/cavium/cn81xx/twsi.c new file mode 100644 index 0000000..a87de79 --- /dev/null +++ b/src/soc/cavium/cn81xx/twsi.c @@ -0,0 +1,20 @@ +/* + * Copyright 2018-present Facebook, Inc. + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <stddef.h> +#include <assert.h> +#include <soc/twsi.h> + +static void *const twsi_bus[] = { + (void *const)0x87E0D0000000ULL, + (void *const)0x87E0D1000000ULL, +}; + +void *twsi_get_baseaddr(const size_t bus) +{ + assert (bus < ARRAY_SIZE(twsi_bus)); + if (bus >= ARRAY_SIZE(twsi_bus)) + return NULL; + return twsi_bus[bus]; +} diff --git a/src/soc/cavium/common/Makefile.inc b/src/soc/cavium/common/Makefile.inc index 2ed9a5e..6777dfc 100644 --- a/src/soc/cavium/common/Makefile.inc +++ b/src/soc/cavium/common/Makefile.inc @@ -16,5 +16,15 @@ ifeq ($(CONFIG_SOC_CAVIUM_COMMON),y) bootblock-$(CONFIG_BOOTBLOCK_CUSTOM) += bootblock.c +bootblock-y += twsi.c + + + +romstage-y += twsi.c + + +ramstage-y += twsi.c + +CPPFLAGS_common += -Isrc/soc/cavium/common/include endif diff --git a/src/soc/cavium/common/i2c.c b/src/soc/cavium/common/i2c.c deleted file mode 100644 index 6c1bdfa..0000000 --- a/src/soc/cavium/common/i2c.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2017-present Facebook, 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; version 2 of the License. - * - * 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. - */ - -/* FIXME: scaffolding based on rk3399 */ - -#include <arch/io.h> -#include <assert.h> -#include <cbfs.h> -#include <console/console.h> -#include <delay.h> -//#include <device/i2c_simple.h> -#include <soc/addressmap.h> -//#include <soc/grf.h> -#include <soc/soc.h> -#include <soc/i2c.h> -//#include <soc/clock.h> -#include <stdlib.h> -#include <string.h> - -#define RETRY_COUNT 3 -/* 100000us = 100ms */ -#define I2C_TIMEOUT_US 100000 -#define I2C_BUS_MAX 6 -#define I2C_NOACK 2 -#define I2C_TIMEOUT 3 - -#define i2c_info(x...) do {if (0) printk(BIOS_DEBUG, x); } while (0) - -#if 0 -struct rk_i2c_regs { - u32 i2c_con; - u32 i2c_clkdiv; - u32 i2c_mrxaddr; - u32 i2c_mrxraddr; - u32 i2c_mtxcnt; - u32 i2c_mrxcnt; - u32 i2c_ien; - u32 i2c_ipd; - u32 i2c_fcnt; - u32 reserved0[(0x100 - 0x24) / 4]; - u32 txdata[8]; - u32 reserved1[(0x200 - 0x120) / 4]; - u32 rxdata[8]; -}; - -static const uintptr_t i2c_bus[] = IC_BASES; - -/* Con register bits. */ -#define I2C_ACT2NAK (1<<6) -#define I2C_NAK (1<<5) -#define I2C_STOP (1<<4) -#define I2C_START (1<<3) -#define I2C_MODE_TX (0<<1) -#define I2C_MODE_TRX (1<<1) -#define I2C_MODE_RX (2<<1) -#define I2C_EN (1<<0) - -#define I2C_8BIT (1<<24) -#define I2C_16BIT (3<<24) -#define I2C_24BIT (7<<24) - -/* Mtxcnt register bits. */ -#define I2C_CNT(cnt) ((cnt) & 0x3F) - -#define I2C_NAKRCVI (1<<6) -#define I2C_STOPI (1<<5) -#define I2C_STARTI (1<<4) -#define I2C_MBRFI (1<<3) -#define I2C_MBTFI (1<<2) -#define I2C_BRFI (1<<1) -#define I2C_BTFI (1<<0) -#define I2C_CLEANI 0x7F -#endif - -static int i2c_send_start(struct cavium_i2c_regs *reg_addr) -{ - /* FIXME: stub */ - printk(BIOS_ERR, "%s: implement this.\n", __func__); - return -1; -#if 0 - int res = 0; - int timeout = I2C_TIMEOUT_US; - - i2c_info("I2c Start::Send Start bit\n"); - write32(®_addr->i2c_ipd, I2C_CLEANI); - write32(®_addr->i2c_con, I2C_EN | I2C_START); - while (timeout--) { - if (read32(®_addr->i2c_ipd) & I2C_STARTI) - break; - udelay(1); - } - - if (timeout <= 0) { - printk(BIOS_ERR, "I2C Start::Send Start Bit Timeout\n"); - res = I2C_TIMEOUT; - } - - return res; -#endif -} - -static int i2c_send_stop(struct cavium_i2c_regs *reg_addr) -{ - /* FIXME: stub */ - printk(BIOS_ERR, "%s: implement this.\n", __func__); - return -1; -#if 0 - int res = 0; - int timeout = I2C_TIMEOUT_US; - - i2c_info("I2c Stop::Send Stop bit\n"); - write32(®_addr->i2c_ipd, I2C_CLEANI); - write32(®_addr->i2c_con, I2C_EN | I2C_STOP); - while (timeout--) { - if (read32(®_addr->i2c_ipd) & I2C_STOPI) - break; - udelay(1); - } - write32(®_addr->i2c_con, 0); - if (timeout <= 0) { - printk(BIOS_ERR, "I2C Stop::Send Stop Bit Timeout\n"); - res = I2C_TIMEOUT; - } - - return res; -#endif -} - -static int i2c_read(struct cavium_i2c_regs *reg_addr, struct i2c_msg segment) -{ - /* FIXME: stub */ - printk(BIOS_ERR, "%s: implement this.\n", __func__); - return -1; -#if 0 - int res = 0; - uint8_t *data = segment.buf; - int timeout = I2C_TIMEOUT_US; - unsigned int bytes_remaining = segment.len; - unsigned int bytes_transferred = 0; - unsigned int words_transferred = 0; - unsigned int rxdata = 0; - unsigned int con = 0; - unsigned int i, j; - - write32(®_addr->i2c_mrxaddr, I2C_8BIT | segment.slave << 1 | 1); - write32(®_addr->i2c_mrxraddr, 0); - con = I2C_MODE_TRX | I2C_EN | I2C_ACT2NAK; - while (bytes_remaining) { - bytes_transferred = MIN(bytes_remaining, 32); - bytes_remaining -= bytes_transferred; - if (!bytes_remaining) - con |= I2C_EN | I2C_NAK; - words_transferred = ALIGN_UP(bytes_transferred, 4) / 4; - - write32(®_addr->i2c_ipd, I2C_CLEANI); - write32(®_addr->i2c_con, con); - write32(®_addr->i2c_mrxcnt, bytes_transferred); - - timeout = I2C_TIMEOUT_US; - while (timeout--) { - if (read32(®_addr->i2c_ipd) & I2C_NAKRCVI) { - write32(®_addr->i2c_mrxcnt, 0); - write32(®_addr->i2c_con, 0); - return I2C_NOACK; - } - if (read32(®_addr->i2c_ipd) & I2C_MBRFI) - break; - udelay(1); - } - if (timeout <= 0) { - printk(BIOS_ERR, "I2C Read::Recv Data Timeout\n"); - write32(®_addr->i2c_mrxcnt, 0); - write32(®_addr->i2c_con, 0); - return I2C_TIMEOUT; - } - - for (i = 0; i < words_transferred; i++) { - rxdata = read32(®_addr->rxdata[i]); - i2c_info("I2c Read::RXDATA[%d] = 0x%x\n", i, rxdata); - for (j = 0; j < 4; j++) { - if ((i * 4 + j) == bytes_transferred) - break; - *data++ = (rxdata >> (j * 8)) & 0xff; - } - } - con = I2C_MODE_RX | I2C_EN | I2C_ACT2NAK; - } - return res; -#endif -} - -static int i2c_write(struct rk_i2c_regs *reg_addr, struct i2c_msg segment) -{ - /* FIXME: stub */ - printk(BIOS_ERR, "%s: implement this.\n", __func__); - return -1; -#if 0 - int res = 0; - uint8_t *data = segment.buf; - int timeout = I2C_TIMEOUT_US; - int bytes_remaining = segment.len + 1; - int bytes_transferred = 0; - int words_transferred = 0; - unsigned int i; - unsigned int j = 1; - u32 txdata = 0; - - txdata |= (segment.slave << 1); - while (bytes_remaining) { - bytes_transferred = MIN(bytes_remaining, 32); - words_transferred = ALIGN_UP(bytes_transferred, 4) / 4; - for (i = 0; i < words_transferred; i++) { - do { - if ((i * 4 + j) == bytes_transferred) - break; - txdata |= (*data++) << (j * 8); - } while (++j < 4); - write32(®_addr->txdata[i], txdata); - j = 0; - i2c_info("I2c Write::TXDATA[%d] = 0x%x\n", i, txdata); - txdata = 0; - } - - write32(®_addr->i2c_ipd, I2C_CLEANI); - write32(®_addr->i2c_con, - I2C_EN | I2C_MODE_TX | I2C_ACT2NAK); - write32(®_addr->i2c_mtxcnt, bytes_transferred); - - timeout = I2C_TIMEOUT_US; - while (timeout--) { - if (read32(®_addr->i2c_ipd) & I2C_NAKRCVI) { - write32(®_addr->i2c_mtxcnt, 0); - write32(®_addr->i2c_con, 0); - return I2C_NOACK; - } - if (read32(®_addr->i2c_ipd) & I2C_MBTFI) - break; - udelay(1); - } - - if (timeout <= 0) { - printk(BIOS_ERR, "I2C Write::Send Data Timeout\n"); - write32(®_addr->i2c_mtxcnt, 0); - write32(®_addr->i2c_con, 0); - return I2C_TIMEOUT; - } - - bytes_remaining -= bytes_transferred; - } - return res; -#endif -} - -static int i2c_do_xfer(void *reg_addr, struct i2c_msg segment) -{ - /* FIXME: stub */ - printk(BIOS_ERR, "%s: implement this.\n", __func__); - return -1; -#if 0 - int res = 0; - - if (i2c_send_start(reg_addr)) - return I2C_TIMEOUT; - if (segment.flags & I2C_M_RD) - res = i2c_read(reg_addr, segment); - else - res = i2c_write(reg_addr, segment); - return i2c_send_stop(reg_addr) || res; -#endif -} - -int platform_i2c_transfer(unsigned bus, struct i2c_msg *segments, - int seg_count) -{ - /* FIXME: stub */ - printk(BIOS_ERR, "%s: implement this.\n", __func__); - return -1; -#if 0 - int i; - int res = 0; - struct rk_i2c_regs *regs = (struct rk_i2c_regs *)(i2c_bus[bus]); - struct i2c_msg *seg = segments; - - for (i = 0; i < seg_count; i++, seg++) { - res = i2c_do_xfer(regs, *seg); - if (res) - break; - } - return res; -#endif -} - -void i2c_init(unsigned int bus, unsigned int hz) -{ - /* FIXME: stub */ - printk(BIOS_ERR, "%s: implement this.\n", __func__); - return -1; -#if 0 - unsigned int clk_div; - unsigned int divl; - unsigned int divh; - unsigned int i2c_src_clk; - unsigned int i2c_clk; - struct rk_i2c_regs *regs = (struct rk_i2c_regs *)(i2c_bus[bus]); - - i2c_src_clk = rkclk_i2c_clock_for_bus(bus); - - /* SCL Divisor = 8*(CLKDIVL + 1 + CLKDIVH + 1) - SCL = PCLK / SCLK Divisor */ - clk_div = div_round_up(i2c_src_clk, hz * 8); - divh = clk_div * 3 / 7 - 1; - divl = clk_div - divh - 2; - i2c_clk = i2c_src_clk / (8 * (divl + 1 + divh + 1)); - printk(BIOS_DEBUG, "I2C bus %u: %uHz (divh = %u, divl = %u)\n", - bus, i2c_clk, divh, divl); - assert((divh < 65536) && (divl < 65536) && hz - i2c_clk < 15*KHz); - write32(®s->i2c_clkdiv, (divh << 16) | (divl << 0)); -#endif -} diff --git a/src/soc/cavium/common/include/soc/twsi.h b/src/soc/cavium/common/include/soc/twsi.h new file mode 100644 index 0000000..a9f23ad --- /dev/null +++ b/src/soc/cavium/common/include/soc/twsi.h @@ -0,0 +1,14 @@ +/* + * Copyright 2018-present Facebook, Inc. + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <types.h> +#include <device/i2c.h> + +#ifndef __SOC_CAVIUM_CN81XX_INCLUDE_SOC_TWSI_H +#define __SOC_CAVIUM_CN81XX_INCLUDE_SOC_TWSI_H + +int twsi_init(unsigned int bus, enum i2c_speed hz); +void *twsi_get_baseaddr(const size_t bus); + +#endif diff --git a/src/soc/cavium/common/twsi.c b/src/soc/cavium/common/twsi.c new file mode 100644 index 0000000..e2ea838 --- /dev/null +++ b/src/soc/cavium/common/twsi.c @@ -0,0 +1,716 @@ +/* + * Copyright 2016 Cavium, Inc. <support(a)cavium.com> + * Copyright 2018-present Facebook, Inc. + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <console/console.h> +#include <soc/twsi.h> +#include <device/i2c.h> +#include <device/i2c_simple.h> +#include <assert.h> +#include <delay.h> +#include <arch/io.h> + + +#define RST_BOOT ((void *const)0x87e006001600ll) +#define PLL_REF_CLK 50000000 /* 50 MHz */ + +#define TWSI_THP 24 + +#define TWSI_SW_TWSI 0x1000 +#define TWSI_TWSI_SW 0x1008 +#define TWSI_INT 0x1010 +#define TWSI_SW_TWSI_EXT 0x1018 + +union rst_boot { + u64 u; + struct { + u64 rboot_pin:1; + u64 rboot:1; + u64 lboot:10; + u64 lboot_ext23:6; + u64 lboot_ext45:6; + u64 reserved_24_29:6; + u64 lboot_oci:3; + u64 pnr_mul:6; + u64 reserved_39_39:1; + u64 c_mul:7; + u64 reserved_47_54:8; + u64 dis_scan:1; + u64 dis_huk:1; + u64 vrm_err:1; + u64 jt_tstmode:1; + u64 ckill_ppdis:1; + u64 trusted_mode:1; + u64 ejtagdis:1; + u64 jtcsrdis:1; + u64 chipkill:1; + } s; +}; + +union twsx_sw_twsi { + u64 u; + struct { + u64 data:32; + u64 eop_ia:3; + u64 ia:5; + u64 addr:10; + u64 scr:2; + u64 size:3; + u64 sovr:1; + u64 r:1; + u64 op:4; + u64 eia:1; + u64 slonly:1; + u64 v:1; + } s; +}; + +union twsx_sw_twsi_ext { + u64 u; + struct { + u64 data:32; + u64 ia:8; + u64 :24; + } s; +}; + +union twsx_int { + u64 u; + struct { + u64 st_int:1; /** TWSX_SW_TWSI register update int */ + u64 ts_int:1; /** TWSX_TWSI_SW register update int */ + u64 core_int:1; /** TWSI core interrupt, ignored for HLC */ + u64 :5; /** Reserved */ + u64 sda_ovr:1; /** SDA testing override */ + u64 scl_ovr:1; /** SCL testing override */ + u64 sda:1; /** SDA signal */ + u64 scl:1; /** SCL signal */ + u64 :52; /** Reserved */ + } s; +}; + +enum { + TWSI_OP_WRITE = 0, + TWSI_OP_READ = 1, +}; + +enum { + TWSI_EOP_SLAVE_ADDR = 0, + TWSI_EOP_CLK_CTL = 3, + TWSI_SW_EOP_IA = 6, +}; + +enum { + TWSI_SLAVEADD = 0, + TWSI_DATA = 1, + TWSI_CTL = 2, + TWSI_CLKCTL = 3, + TWSI_STAT = 3, + TWSI_SLAVEADD_EXT = 4, + TWSI_RST = 7, +}; + +enum { + TWSI_CTL_AAK = (1 << 2), + TWSI_CTL_IFLG = (1 << 3), + TWSI_CTL_STP = (1 << 4), + TWSI_CTL_STA = (1 << 5), + TWSI_CTL_ENAB = (1 << 6), + TWSI_CTL_CE = (1 << 7), +}; + +enum { + /** Bus error */ + TWSI_STAT_BUS_ERROR = 0x00, + /** Start condition transmitted */ + TWSI_STAT_START = 0x08, + /** Repeat start condition transmitted */ + TWSI_STAT_RSTART = 0x10, + /** Address + write bit transmitted, ACK received */ + TWSI_STAT_TXADDR_ACK = 0x18, + /** Address + write bit transmitted, /ACK received */ + TWSI_STAT_TXADDR_NAK = 0x20, + /** Data byte transmitted in master mode, ACK received */ + TWSI_STAT_TXDATA_ACK = 0x28, + /** Data byte transmitted in master mode, ACK received */ + TWSI_STAT_TXDATA_NAK = 0x30, + /** Arbitration lost in address or data byte */ + TWSI_STAT_TX_ARB_LOST = 0x38, + /** Address + read bit transmitted, ACK received */ + TWSI_STAT_RXADDR_ACK = 0x40, + /** Address + read bit transmitted, /ACK received */ + TWSI_STAT_RXADDR_NAK = 0x48, + /** Data byte received in master mode, ACK transmitted */ + TWSI_STAT_RXDATA_ACK_SENT = 0x50, + /** Data byte received, NACK transmitted */ + TWSI_STAT_RXDATA_NAK_SENT = 0x58, + /** Slave address received, sent ACK */ + TWSI_STAT_SLAVE_RXADDR_ACK = 0x60, + /** + * Arbitration lost in address as master, slave address + write bit + * received, ACK transmitted + */ + TWSI_STAT_TX_ACK_ARB_LOST = 0x68, + /** General call address received, ACK transmitted */ + TWSI_STAT_RX_GEN_ADDR_ACK = 0x70, + /** + * Arbitration lost in address as master, general call address + * received, ACK transmitted + */ + TWSI_STAT_RX_GEN_ADDR_ARB_LOST = 0x78, + /** Data byte received after slave address received, ACK transmitted */ + TWSI_STAT_SLAVE_RXDATA_ACK = 0x80, + /** Data byte received after slave address received, /ACK transmitted */ + TWSI_STAT_SLAVE_RXDATA_NAK = 0x88, + /** + * Data byte received after general call address received, ACK + * transmitted + */ + TWSI_STAT_GEN_RXADDR_ACK = 0x90, + /** + * Data byte received after general call address received, /ACK + * transmitted + */ + TWSI_STAT_GEN_RXADDR_NAK = 0x98, + /** STOP or repeated START condition received in slave mode */ + TWSI_STAT_STOP_MULTI_START = 0xA0, + /** Slave address + read bit received, ACK transmitted */ + TWSI_STAT_SLAVE_RXADDR2_ACK = 0xA8, + /** + * Arbitration lost in address as master, slave address + read bit + * received, ACK transmitted + */ + TWSI_STAT_RXDATA_ACK_ARB_LOST = 0xB0, + /** Data byte transmitted in slave mode, ACK received */ + TWSI_STAT_SLAVE_TXDATA_ACK = 0xB8, + /** Data byte transmitted in slave mode, /ACK received */ + TWSI_STAT_SLAVE_TXDATA_NAK = 0xC0, + /** Last byte transmitted in slave mode, ACK received */ + TWSI_STAT_SLAVE_TXDATA_END_ACK = 0xC8, + /** Second address byte + write bit transmitted, ACK received */ + TWSI_STAT_TXADDR2DATA_ACK = 0xD0, + /** Second address byte + write bit transmitted, /ACK received */ + TWSI_STAT_TXADDR2DATA_NAK = 0xD8, + /** No relevant status information */ + TWSI_STAT_IDLE = 0xF8 +}; + +/** + * Returns true if we lost arbitration + * + * @param code status code + * @param final_read true if this is the final read operation + * + * @return true if arbitration has been lost, false if it hasn't been lost. + */ +static int twsi_i2c_lost_arb(u8 code, int final_read) +{ + switch (code) { + /* Arbitration lost */ + case TWSI_STAT_TX_ARB_LOST: + case TWSI_STAT_TX_ACK_ARB_LOST: + case TWSI_STAT_RX_GEN_ADDR_ARB_LOST: + case TWSI_STAT_RXDATA_ACK_ARB_LOST: + return -1; + + /* Being addressed as slave, should back off and listen */ + case TWSI_STAT_SLAVE_RXADDR_ACK: + case TWSI_STAT_RX_GEN_ADDR_ACK: + case TWSI_STAT_GEN_RXADDR_ACK: + case TWSI_STAT_GEN_RXADDR_NAK: + return -1; + + /* Core busy as slave */ + case TWSI_STAT_SLAVE_RXDATA_ACK: + case TWSI_STAT_SLAVE_RXDATA_NAK: + case TWSI_STAT_STOP_MULTI_START: + case TWSI_STAT_SLAVE_RXADDR2_ACK: + case TWSI_STAT_SLAVE_TXDATA_ACK: + case TWSI_STAT_SLAVE_TXDATA_NAK: + case TWSI_STAT_SLAVE_TXDATA_END_ACK: + return -1; + + /* Ack allowed on pre-terminal bytes only */ + case TWSI_STAT_RXDATA_ACK_SENT: + if (!final_read) + return 0; + return -1; + + /* NAK allowed on terminal byte only */ + case TWSI_STAT_RXDATA_NAK_SENT: + if (!final_read) + return 0; + return -1; + + case TWSI_STAT_TXDATA_NAK: + case TWSI_STAT_TXADDR_NAK: + case TWSI_STAT_RXADDR_NAK: + case TWSI_STAT_TXADDR2DATA_NAK: + return -1; + } + return 0; +} + +#define RST_BOOT_PNR_MUL(Val) ((Val >> 33) & 0x1F) + +/** + * Writes to the MIO_TWS(0..5)_SW_TWSI register + * + * @param baseaddr Base address of i2c registers + * @param sw_twsi value to write + * + * @return 0 for success, otherwise error + */ +static u64 twsi_write_sw(void *baseaddr, union twsx_sw_twsi sw_twsi) +{ + unsigned long timeout = 500000; + + sw_twsi.s.r = 0; + sw_twsi.s.v = 1; + + printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u); + write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u); + do { + sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI); + timeout--; + } while (sw_twsi.s.v != 0 && timeout > 0); + + if (sw_twsi.s.v) + printk(BIOS_ERR, "%s: timed out\n", __func__); + return sw_twsi.u; +} + +/** + * Reads the MIO_TWS(0..5)_SW_TWSI register + * + * @param baseaddr Base address of i2c registers + * @param sw_twsi value for eia and op, etc. to read + * + * @return value of the register + */ +static u64 twsi_read_sw(void *baseaddr, union twsx_sw_twsi sw_twsi) +{ + unsigned long timeout = 500000; + sw_twsi.s.r = 1; + sw_twsi.s.v = 1; + + printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u); + write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u); + + do { + sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI); + timeout--; + } while (sw_twsi.s.v != 0 && timeout > 0); + + if (sw_twsi.s.v) + printk(BIOS_ERR, "%s: Error writing 0x%llx\n", __func__, + sw_twsi.u); + + printk(BIOS_SPEW, "%s: Returning 0x%llx\n", __func__, sw_twsi.u); + return sw_twsi.u; +} + +/** + * Write control register + * + * @param baseaddr Base address for i2c registers + * @param data data to write + */ +static void twsi_write_ctl(void *baseaddr, const u8 data) +{ + union twsx_sw_twsi twsi_sw; + + printk(BIOS_SPEW, "%s(%p, 0x%x)\n", __func__, baseaddr, data); + twsi_sw.u = 0; + + twsi_sw.s.op = TWSI_SW_EOP_IA; + twsi_sw.s.eop_ia = TWSI_CTL; + twsi_sw.s.data = data; + + twsi_write_sw(baseaddr, twsi_sw); +} + +/** + * Reads the TWSI Control Register + * + * @param[in] baseaddr Base address for i2c + * + * @return 8-bit TWSI control register + */ +static u32 twsi_read_ctl(void *baseaddr) +{ + union twsx_sw_twsi sw_twsi; + + sw_twsi.u = 0; + sw_twsi.s.op = TWSI_SW_EOP_IA; + sw_twsi.s.eop_ia = TWSI_CTL; + + sw_twsi.u = twsi_read_sw(baseaddr, sw_twsi); + printk(BIOS_SPEW, "%s(%p): 0x%x\n", __func__, baseaddr, sw_twsi.s.data); + return sw_twsi.s.data; +} + +/** + * Read i2c status register + * + * @param baseaddr Base address of i2c registers + * + * @return value of status register + */ +static u8 twsi_read_status(void *baseaddr) +{ + union twsx_sw_twsi twsi_sw; + + twsi_sw.u = 0; + twsi_sw.s.op = TWSI_SW_EOP_IA; + twsi_sw.s.eop_ia = TWSI_STAT; + + return twsi_read_sw(baseaddr, twsi_sw); +} + +/** + * Waits for an i2c operation to complete + * + * @param baseaddr Base address of registers + * + * @return 0 for success, 1 if timeout + */ +static int twsi_wait(void *baseaddr) +{ + unsigned long timeout = 500000; + u8 twsi_ctl; + + printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr); + do { + twsi_ctl = twsi_read_ctl(baseaddr); + twsi_ctl &= TWSI_CTL_IFLG; + timeout--; + } while (!twsi_ctl && timeout > 0); + + printk(BIOS_SPEW, " return: %u\n", !twsi_ctl); + return !twsi_ctl; +} + +/** + * Sends an i2c stop condition + * + * @param baseaddr register base address + * + * @return 0 for success, -1 if error + */ +static int twsi_stop(void *baseaddr) +{ + u8 stat; + twsi_write_ctl(baseaddr, TWSI_CTL_STP | TWSI_CTL_ENAB); + + stat = twsi_read_status(baseaddr); + if (stat != TWSI_STAT_IDLE) { + printk(BIOS_ERR, "%s: Bad status on bus@%p\n", __func__, + baseaddr); + return -1; + } + return 0; +} + +/** + * Manually clear the I2C bus and send a stop + */ +static void twsi_unblock(void *baseaddr) +{ + int i; + union twsx_int int_reg; + + int_reg.u = 0; + for (i = 0; i < 9; i++) { + int_reg.s.scl_ovr = 0; + write64(baseaddr + TWSI_INT, int_reg.u); + udelay(5); + int_reg.s.scl_ovr = 1; + write64(baseaddr + TWSI_INT, int_reg.u); + udelay(5); + } + int_reg.s.sda_ovr = 1; + write64(baseaddr + TWSI_INT, int_reg.u); + udelay(5); + int_reg.s.scl_ovr = 0; + write64(baseaddr + TWSI_INT, int_reg.u); + udelay(5); + int_reg.u = 0; + write64(baseaddr + TWSI_INT, int_reg.u); + udelay(5); +} + +/** + * Unsticks the i2c bus + * + * @param baseaddr base address of registers + */ +static int twsi_start_unstick(void *baseaddr) +{ + twsi_stop(baseaddr); + + twsi_unblock(baseaddr); + + return 0; +} + +/** + * Sends an i2c start condition + * + * @param baseaddr base address of registers + * + * @return 0 for success, otherwise error + */ +static int twsi_start(void *baseaddr) +{ + int result; + u8 stat; + + printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr); + twsi_write_ctl(baseaddr, TWSI_CTL_STA | TWSI_CTL_ENAB); + result = twsi_wait(baseaddr); + if (result) { + stat = twsi_read_status(baseaddr); + printk(BIOS_SPEW, "%s: result: 0x%x, status: 0x%x\n", __func__, + result, stat); + switch (stat) { + case TWSI_STAT_START: + case TWSI_STAT_RSTART: + return 0; + case TWSI_STAT_RXADDR_ACK: + default: + return twsi_start_unstick(baseaddr); + } + } + printk(BIOS_SPEW, "%s: success\n", __func__); + return 0; +} + +/** + * Writes data to the i2c bus + * + * @param baseraddr register base address + * @param slave_addr address of slave to write to + * @param buffer Pointer to buffer to write + * @param length Number of bytes in buffer to write + * + * @return 0 for success, otherwise error + */ +static int twsi_write_data(void *baseaddr, const u8 slave_addr, + const u8 *buffer, const unsigned int length) +{ + union twsx_sw_twsi twsi_sw; + unsigned int curr = 0; + int result; + + printk(BIOS_DEBUG, "%s(%p, 0x%x, %p, 0x%x)\n", __func__, baseaddr, + slave_addr, buffer, length); + result = twsi_start(baseaddr); + if (result) { + printk(BIOS_ERR, "%s: Could not start BUS transaction\n", + __func__); + return -1; + } + + result = twsi_wait(baseaddr); + if (result) { + printk(BIOS_ERR, "%s: wait failed\n", __func__); + return result; + } + + twsi_sw.u = 0; + twsi_sw.s.op = TWSI_SW_EOP_IA; + twsi_sw.s.eop_ia = TWSI_DATA; + twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_WRITE; + + twsi_write_sw(baseaddr, twsi_sw); + twsi_write_ctl(baseaddr, TWSI_CTL_ENAB); + + printk(BIOS_DEBUG, "%s: Waiting\n", __func__); + result = twsi_wait(baseaddr); + if (result) { + printk(BIOS_ERR, "%s: Timed out writing slave address 0x%x\n", + __func__, slave_addr); + return result; + } + result = twsi_read_status(baseaddr); + if ((result = twsi_read_status(baseaddr)) != TWSI_STAT_TXADDR_ACK) { + twsi_stop(baseaddr); + return twsi_i2c_lost_arb(result, 0); + } + + while (curr < length) { + twsi_sw.u = 0; + twsi_sw.s.op = TWSI_SW_EOP_IA; + twsi_sw.s.eop_ia = TWSI_DATA; + twsi_sw.s.data = buffer[curr++]; + + twsi_write_sw(baseaddr, twsi_sw); + twsi_write_ctl(baseaddr, TWSI_CTL_ENAB); + + result = twsi_wait(baseaddr); + if (result) { + printk(BIOS_ERR, "%s: Timed out writing data to 0x%x\n", + __func__, slave_addr); + return result; + } + } + + printk(BIOS_DEBUG, "%s: Stopping\n", __func__); + return twsi_stop(baseaddr); +} + +/** + * Performs a read transaction on the i2c bus + * + * @param baseaddr Base address of twsi registers + * @param slave_addr i2c bus address to read from + * @param buffer buffer to read into + * @param length number of bytes to read + * + * @return 0 for success, otherwise error + */ +static int twsi_read_data(void *baseaddr, const u8 slave_addr, + u8 *buffer, const unsigned int length) +{ + union twsx_sw_twsi twsi_sw; + unsigned int curr = 0; + int result; + + printk(BIOS_DEBUG, "%s(%p, 0x%x, %p, %u)\n", __func__, baseaddr, + slave_addr, buffer, length); + result = twsi_start(baseaddr); + if (result) { + printk(BIOS_ERR, "%s: start failed\n", __func__); + return result; + } + + result = twsi_wait(baseaddr); + if (result) { + printk(BIOS_ERR, "%s: wait failed\n", __func__); + return result; + } + + twsi_sw.u = 0; + twsi_sw.s.op = TWSI_SW_EOP_IA; + twsi_sw.s.eop_ia = TWSI_DATA; + + twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_READ; + + twsi_write_sw(baseaddr, twsi_sw); + twsi_write_ctl(baseaddr, TWSI_CTL_ENAB); + + result = twsi_wait(baseaddr); + if (result) { + printk(BIOS_ERR, "%s: waiting for sending addr failed\n", __func__); + return result; + } + + result = twsi_read_status(baseaddr); + if (result != TWSI_STAT_RXADDR_ACK) { + twsi_stop(baseaddr); + return twsi_i2c_lost_arb(result, 0); + } + + while (curr < length) { + twsi_write_ctl(baseaddr, TWSI_CTL_ENAB | + ((curr < length - 1) ? TWSI_CTL_AAK : 0)); + + result = twsi_wait(baseaddr); + if (result) { + printk(BIOS_ERR, "%s: waiting for data failed\n", + __func__); + return result; + } + + twsi_sw.u = twsi_read_sw(baseaddr, twsi_sw); + buffer[curr++] = twsi_sw.s.data; + } + + twsi_stop(baseaddr); + + return 0; +} + +static int twsi_set_speed(void *baseaddr, const unsigned int speed) +{ + int io_clock_hz; + int n_div; + int m_div; + union twsx_sw_twsi sw_twsi; + union rst_boot rst_boot; + + printk(BIOS_DEBUG, "%s(%p, %u)\n", __func__, baseaddr, speed); + rst_boot.u = read64(RST_BOOT); + + io_clock_hz = rst_boot.s.pnr_mul * PLL_REF_CLK; + + /* Set the TWSI clock to a conservative TWSI_BUS_FREQ. Compute the + * clocks M divider based on the SCLK. + * TWSI freq = (core freq) / (20 x (M+1) x (thp+1) x 2^N) + * M = ((core freq) / (20 x (TWSI freq) x (thp+1) x 2^N)) - 1 + */ + for (n_div = 0; n_div < 8; n_div++) { + m_div = io_clock_hz / (20 * speed * (TWSI_THP + 1)); + m_div /= 1 << n_div; + m_div -= 1; + if (m_div < 16) + break; + } + if (m_div >= 16) + return -1; + + sw_twsi.u = 0; + sw_twsi.s.v = 1; + sw_twsi.s.op = 0x6; /* See EOP field */ + sw_twsi.s.r = 0; /* Select CLKCTL when R = 0 */ + sw_twsi.s.eop_ia = 3; /* R=0 selects CLKCTL, R=1 selects STAT */ + sw_twsi.s.data = ((m_div & 0xf) << 3) | ((n_div & 0x7) << 0); + + twsi_write_sw(baseaddr, sw_twsi); + return 0; +} + +int twsi_init(unsigned int bus, enum i2c_speed hz) +{ + void *baseaddr = twsi_get_baseaddr(bus); + if (!baseaddr) + return -1; + + if (twsi_set_speed(baseaddr, hz) < 0) + return -1; + + /* Enable TWSI, HLC disable, STOP, NAK */ + twsi_write_ctl(baseaddr, TWSI_CTL_ENAB); + + return 0; +} + +int platform_i2c_transfer(unsigned bus, struct i2c_msg *segments, + int seg_count) +{ + int result; + void *baseaddr = twsi_get_baseaddr(bus); + if (!baseaddr) + return -1; + + printk(BIOS_SPEW, "%s: %d messages\n", __func__, seg_count); + for (; seg_count > 0; seg_count--, segments++) { + if (segments->flags & I2C_M_RD) { + result = twsi_read_data(baseaddr, segments->slave, + segments->buf, segments->len); + } else { + result = twsi_write_data(baseaddr, segments->slave, + segments->buf, segments->len); + } + if (result) { + printk(BIOS_ERR, "%s: error transmitting data\n", + __func__); + return -1; + } + } + + return 0; +} -- To view, visit
https://review.coreboot.org/23751
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: I9f85d024b3ffd0a0c4376a8880d14db9e3570d79 Gerrit-Change-Number: 23751 Gerrit-PatchSet: 1 Gerrit-Owner: Patrick Rudolph <patrick.rudolph(a)9elements.com>
1
0
0
0
Change in coreboot[master]: security/tpm: Add SW hash functions for measurements
by build bot (Jenkins) (Code Review)
14 Feb '18
14 Feb '18
build bot (Jenkins) has posted comments on this change. (
https://review.coreboot.org/23711
) Change subject: security/tpm: Add SW hash functions for measurements ...................................................................... Patch Set 6: Verified+1 Build Successful
https://qa.coreboot.org/job/coreboot-gerrit/67454/
: SUCCESS -- To view, visit
https://review.coreboot.org/23711
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-MessageType: comment Gerrit-Change-Id: Ice8a0de0294fe619ff725dc5126319fc2bc657ad Gerrit-Change-Number: 23711 Gerrit-PatchSet: 6 Gerrit-Owner: Philipp Deppenwiese <zaolin.daisuki(a)gmail.com> Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org> Gerrit-Reviewer: Paul Menzel <paulepanter(a)users.sourceforge.net> Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org> Gerrit-Comment-Date: Wed, 14 Feb 2018 13:48:48 +0000 Gerrit-HasComments: No Gerrit-HasLabels: Yes
1
0
0
0
← Newer
1
...
72
73
74
75
76
77
78
...
158
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
Results per page:
10
25
50
100
200