[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