[coreboot] How to read the gpio status?

김유석 poplinux0 at gmail.com
Wed Jul 20 10:19:12 CEST 2016


Dear Zoran.

_I was perectly understand the I2C algo_. It is very easy to me.

And I was know that I2C_DATA line is must need a mode 
change(INPUT/OUTPUT) for bidirectional communication.

*At present, I2C is not important to me.*

I want to say. that my purpose is just control GPIO pins.


My problem is...

Suppose this sistuation.

Initial status of gpio

pin
	SC_IO_SEL
	SC_GP_LVL
GPIO_11(reset of some ic)
	output
	HIGH
GPIO_12(LED1)
	output
	LOW
GPIO_13(detect pin)
	input
	HIGH



After power-on. suppose, must need turn on  the GPIO_12(LED1).
It is easy.

void led_control(u32 pin_num)
{
    u32 current_status = inl(gbase + SC_GP_LVL);
    current_status = setbit(current_status, pin_num);
}


*But, My case is can't read status of outputmode pins.*
      Can read the status of *inputmode pins*.
ButCan't read the status of *outputmode pins.*
current status is very important information for bit operation(set/clear).

   GPIO_11 is output mode => can't read this status.
   GPIO_12 is output mode => can't read this status.
GPIO_13 is input mode => can read this status.

If I try to control without knowing the current state, *must becomes 
problem.*

So, I try to find the solution that "How to read the status of 
outputmode gpio pins"


Another platform is can get a status of pin. use by "register of IO 
direction" and "register of IO Level".

If I use the AND operation, can get a status of output mode pins.


Please any idea?

Thank you.








2016-07-20 오후 3:56에 Zoran Stojsavljevic 이(가) 쓴 글:
> 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 
> <mailto: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.
>>
>>     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
>>     <mailto: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
>>>         <mailto: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
>>>             <mailto: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/d4159be4/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/d4159be4/attachment-0001.png>


More information about the coreboot mailing list