[coreboot] How to read the gpio status?
Zoran Stojsavljevic
zoran.stojsavljevic at gmail.com
Wed Jul 20 08:56:14 CEST 2016
Hello Kim,
Kim, listen to me/read me now very carefully. Please. :-)
For the standard I2C interface, you have only two serial lines: I2C_CLK and
I2C_DATA. Your C2000 is master, so it will ALWAYS provide I2C_CLK as OUT.
With I2C_DATA things are a bit more complicated. It is IN/OUT line, and
once you output on it, you MUST turn it around.
I'll provide to you an adequate example. Let us assume SC_USE_SEL has two
dedicated IO_14 as I2C_CLK, and IO_13 as I2C_DATA.
For the I2C_CLK, it is always output. For I2C_DATA, it is bidirectional.
So, when you supply slave I2C address on the bus, the following is true:
GPIO_SC_USE_SEL : 6000
GPIO_SC_IO_SEL : 0 (all pins as OUT direction)
GPIO_SC_GP_LVL : bit banging on pins 13, 14
Now, you need to turn around your data bus, to be IN. Here is the situation:
GPIO_SC_USE_SEL : 6000
GPIO_SC_IO_SEL : 2000 (pin 13 is now defined as IN direction!)
GPIO_SC_GP_LVL : answer coming on pin 13, you have to sample it correctly
in time READing this register (only bit 13 is valid) and looking into bit
13 value).
You might try it. And I rest my case here, Kim!
Zoran
On Wed, Jul 20, 2016 at 6:52 AM, 김유석 <poplinux0 at gmail.com> wrote:
> Dear Sir.
>
> I'm understand your worry.
>
> My phase is develop the raw level API for gpio control.
> SW I2C is will use the raw level API. SW I2C is will implementation.
>
> I was set the SC_USE_SEL, and SC_IO_SEL. correctly.
>
> And I already check the some function.
> 1. outmode => is OK.
> If i set the HIGH on 12, 13, 14. then i can saw the HIGH status
> using ocilloscope.
> If i set the LOW on 12, 13, 14. then i can saw the LOW status using
> ocilloscope.
> 2. input mode => is OK.
> If i assign the 3.3V to 12, 13, 14. then i can read the
> SC_GP_LVL(0x7000).
> If i assign the 0V to 12, 13, 14. then i can read the SC_GP_LVL(0x00)
>
> But just one function is fail.
>
> step 1. set the output mode. => is success
> step 2. set the level. => is success
> step 3. read the current config of SC_GP_LVL => is fail.
> if if write 0x7000 to SC_GP_LVL, I want to read the value 0x7000
> from SC_GP_LVL. But i can't
>
> Thank you.
>
>
>
>
> 2016-07-19 오후 9:12에 Zoran Stojsavljevic 이(가) 쓴 글:
>
> Hey Kim,
>
> You have forced me myself to read the manual (chapter 25, C2000 Data
> Sheet). I was really wondering... So I decided to spend some time and read
> it myself (anyway, I have some time, albeit I do some other stuff). ;-)
>
> There is description of two power domains there, which I/O are using in
> order to drive customer I/O wishes. Two of them are: Core Well and SUS
> Well. You are using Core Well GPIOs, namely they are described in Ch.
> 25.3.1:
> Choosing the native Signal Mode or Customer GPIO Mode.
>
> [image: Inline image 1]
>
> Questions here: did you set properly register: SC_USE_SEL? Your bits
> 12/13/14 should be in this register 1s (x111 xxxx xxxx xxxx binary), and
> you need to set also properly SC_IO_SEL register (them to be outputs). I am
> now looking into your code, and it seems you did it correctly (three OUT
> values):
> GPIO_SC_USE_SEL : 7000
> GPIO_SC_IO_SEL : 0
> GPIO_SC_GP_LVL : 0
>
> Then you output your OUT values. Hmmmmmm... Considering I2C, you
> inevitable should read some INPUT values?! Which pins these are? You should
> have from master (your C2000) to supply CLK and OUT, but you also need to
> read IN values... Don't you???
>
> I do NOT see input from I2C slave device... Any thoughts (any ideas)?
>
> Zoran
>
> On Mon, Jul 18, 2016 at 7:20 AM, 김유석 <poplinux0 at gmail.com> wrote:
>
>> Dear Sir.
>>
>> I was test with by your advise. But SC_GP_LVL is always read 0x00
>>
>> source code & result is see below.
>>
>> u32 read_gpio_level(const struct soc_gpio_map *gpio)
>> {
>>
>> u16 gpiobase __attribute__((unused)) = pci_read_config16(SOC_LPC_DEV,
>> GBASE) & ~0xf;
>>
>> printk(BIOS_DEBUG, "%s() : Start\n", __FUNCTION__);
>> printk(BIOS_DEBUG, " GPIO_SC_USE_SEL : 0x%x\n", inl(gpiobase +
>> GPIO_SC_USE_SEL));
>> printk(BIOS_DEBUG, " GPIO_SC_IO_SEL : 0x%x\n", inl(gpiobase +
>> GPIO_SC_IO_SEL));
>> printk(BIOS_DEBUG, " GPIO_SC_GP_LVL : 0x%x\n", inl(gpiobase +
>> GPIO_SC_GP_LVL));
>> printk(BIOS_DEBUG, "%s() : End\n\n", __FUNCTION__);
>>
>> return 0;
>> }
>>
>> int set_gpio_level(const struct soc_gpio_map *gpio,
>> const int num,
>> const int lvl)
>> {
>> u16 gpiobase __attribute__((unused)) = pci_read_config16(SOC_LPC_DEV,
>> GBASE) & ~0xf;
>> u32 GPIO = 0;
>>
>> GPIO = setBit(GPIO, num);
>>
>> printk(BIOS_DEBUG, "%s() : GPIO set value 0x%x\n", __FUNCTION__,
>> GPIO);
>> outl(GPIO, gpiobase + GPIO_SC_GP_LVL);
>>
>> return 0;
>> }
>>
>>
>> void early_mainboard_romstage_entry(void)
>> {
>> setup_soc_gpios(&gpio_map);
>> set_gpio_level(&gpio_map, 12, 1);
>> mdelay(500);
>> read_gpio_level(&gpio_map);
>>
>> set_gpio_level(&gpio_map, 13, 1);
>> mdelay(500);
>> read_gpio_level(&gpio_map);
>>
>> set_gpio_level(&gpio_map, 14, 1);
>> mdelay(500);
>> read_gpio_level(&gpio_map);
>> };
>>
>>
>>
>> ==================================================================================
>> coreboot-NexG-59a9b0a6 Mon Jul 18 05:09:30 UTC 2016 romstage starting...
>> set_gpio_level() : GPIO set value 0x1000
>> read_gpio_level() : Start
>> GPIO_SC_USE_SEL : 7000
>> GPIO_SC_IO_SEL : 0
>> GPIO_SC_GP_LVL : 0
>> read_gpio_level() : End
>>
>> set_gpio_level() : GPIO set value 0x2000
>> read_gpio_level() : Start
>> GPIO_SC_USE_SEL : 7000
>> GPIO_SC_IO_SEL : 0
>> GPIO_SC_GP_LVL : 0
>> read_gpio_level() : End
>>
>> set_gpio_level() : GPIO set value 0x4000
>> read_gpio_level() : Start
>> GPIO_SC_USE_SEL : 7000
>> GPIO_SC_IO_SEL : 0
>> GPIO_SC_GP_LVL : 0
>> read_gpio_level() : End
>>
>>
>>
>>
>>
>> And I was re-view the DS of C2000.
>>
>> But DS is said to me that SC_GP_LVL is WR register.
>>
>>
>>
>> Please help me.
>>
>> Thank you.
>>
>>
>>
>>
>> 2016-07-13 오후 4:40에 Zoran Stojsavljevic 이(가) 쓴 글:
>>
>> *> When write 0x7000 write to SC_GP_LVL, Can read the 0x00 from
>> SC_GP_LVL. everytime.*
>>
>> Please, try to do the following exercise:
>>
>> [1] WR 0x1000 to SC_GP_LVL, then RD the value out of it: what it is?
>> [2] WR 0x2000 to SC_GP_LVL, then RD the value out of it: what it is?
>> [3] WR 0x4000 to SC_GP_LVL, then RD the value out of it: what it is?
>>
>> If you have all 0x0, most likely it does mean that Rangeley's SC_GP_LVL
>> register isd WR ONLY (when you read it, all 0s).
>>
>> To verify this, you should fetch the following document:
>>
>> http://www.intel.com/content/www/us/en/processors/atom/atom-c2000-microserver-datasheet.html
>>
>> And read Chapter 25 - General Purpose I/O (GPIO).
>>
>> Best Regards,
>> Zoran
>>
>> On Wed, Jul 13, 2016 at 6:39 AM, 김유석 <poplinux0 at gmail.com> wrote:
>>
>>> Dear Sir.
>>>
>>>
>>> I want to control the GPIO pin that pin number is 12, 13, 14
>>>
>>>
>>> DataSheet(P 1909) and coreboot source
>>> code(src/southbridge/intel/fsp_rangeley/gpio.c, gpio.h) is said to me that
>>> "It is very easy"
>>>
>>>
>>> If i want to set the HIGH to 12, 13, 14
>>>
>>> Just setup the some register, is see below.
>>>
>>> SC_USE_SEL = 0x7000(b0111 0000 0000 0000)
>>>
>>> Is mean, the 12, 13, 14 is config to GPIO mode.(enable GPIO)
>>>
>>> SC_IO_SEL = 0x00(b0000 0000 0000 0000)
>>>
>>> Is mean, the 12, 13, 14 is output mode
>>>
>>> SC_GP_LVL = 0x7000(b0111 0000 0000 0000)
>>>
>>> Is mean, the 12, 13, 14 is set to HIGH level(1)
>>>
>>>
>>> src/southbridge/intel/fsp_rangeley/gpio.h
>>>
>>> /* Core GPIO */
>>> const struct soc_gpio soc_gpio_mode = {
>>> .gpio12 = GPIO_MODE_GPIO, /* Board ID GPIO */
>>> .gpio13 = GPIO_MODE_GPIO, /* Board ID GPIO */
>>> .gpio14 = GPIO_MODE_GPIO, /* Board ID GPIO */
>>> };
>>>
>>> const struct soc_gpio soc_gpio_direction = {
>>> .gpio12 = GPIO_DIR_OUTPUT,
>>> .gpio13 = GPIO_DIR_OUTPUT,
>>> .gpio14 = GPIO_DIR_OUTPUT,
>>> };
>>>
>>> const struct soc_gpio soc_gpio_level = {
>>> .gpio12 = GPIO_LEVEL_HIGH,
>>> .gpio13 = GPIO_LEVEL_HIGH,
>>> .gpio14 = GPIO_LEVEL_HIGH,
>>> };
>>>
>>>
>>> Yes, It is perfectley running.
>>>
>>> The 12, 13, 14 PIN is goto active-HIGH.(I was check this pin use by
>>> oscilloscope.)
>>>
>>>
>>> And I'm try to read the SC_GP_LVL register for check current
>>> status/config of gpio pins
>>>
>>> I was *respected* the read value is *0x7000*, because i was writed the
>>> *0x7000* to SC_GP_LVL.
>>>
>>>
>>> But, every time readed the *0x00* from SC_GP_LVL register.
>>>
>>>
>>> *When write 0x7000 write to SC_USE_SEL, Can read the 0x7000 from
>>> SC_USE_SEL.*
>>>
>>> *When write 0x00 write to SC_IO_SEL, Can read the 0x00 from SC_IO_SEL.*
>>>
>>>
>>> But,
>>>
>>>
>>> *When write 0x7000 write to SC_GP_LVL, Can read the 0x00 from SC_GP_LVL.
>>> everytime.*
>>>
>>>
>>> I don't understand this sistuation.
>>>
>>>
>>> Please advise to me.
>>>
>>>
>>> Thank you.
>>>
>>>
>>>
>>>
>>>
>>>
>>> --
>>> coreboot mailing list: coreboot at coreboot.org
>>> https://www.coreboot.org/mailman/listinfo/coreboot
>>>
>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20160720/b1e15f1c/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: image/png
Size: 113547 bytes
Desc: not available
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20160720/b1e15f1c/attachment-0001.png>
More information about the coreboot
mailing list