[coreboot] How to read the gpio status?

Zoran Stojsavljevic zoran.stojsavljevic at gmail.com
Tue Jul 19 11:42:50 CEST 2016


Hello 김유석,

I did not understand (very imporatnt question): why at all you do need SW
I2C (bit-banging I2C) in Coreboot romstage? Maybe you can move your I2C
operation later, in ramstage?!

Isn't romstage just to do very quick boot and pass the phase where MRC
(DDRs) should be initialized? And not sure if both L1 cashes are set as CAR
(L1 I-cache as well as L1 D-cache)? It seems to me that only L1 D-cache is
initialized as CAR, L1 I-cache remains to be true cache for flash code to
be executed fast.

I do know that romstage is compiled with the special ROMCC compiler, which
was adopted by Eric Biederman (2003-2006, ebiederman at lnxi.com):
https://github.com/wt/coreboot/blob/master/util/romcc/romcc.1

Maybe, this compiler allows you to store your outl() value into some 32-bit
reserved (for this purpose) common purpose register (instead of global
variable), but at this point in time, I need more time to investigate ROMCC.

Some other people very well might know answers about ROMCC on coreboot
mailing list. ;-)

Zoran

On Tue, Jul 19, 2016 at 8:40 AM, 김유석 <poplinux0 at gmail.com> wrote:

> Sorry. i was have a miss-typing.
>
> I can read the some global variable. => X
> I can't read the some global variable. => O
>
>
>
> Thank you.
>
>
>
> 2016-07-19 오후 3:26에 김유석 이(가) 쓴 글:
>
> Dear Sir.
>
> Thank's your advise.
>
> I can read the some global variable.
> Because the outl() api is directly write value to register. Not global
> variable. I guess.
>
> Perhaps, your mean is a must use GLOBAL value for SC_GP_LVL?(do not try to
> read from SC_GP_LVL)
> I was try to use the GLOBAL value on coreboot. But occured the compile
> error.
>
> the global value "u32 val_sc_gp_lvl" is defined on
> "src/southbridge/intel/fsp_rangeley/gpio.c"
> and use this value is on
> "src/southbridge/intel/fsp_rangeley/gpio.c::setup_soc_gpios()"
>
> If i call setup_soc_gpios() is
> "src/mainboard/intel/mohonpeak/romstage.c::early_mainboard_romstage_entry()",
> occured build error. log is see below.
>
>     OBJCOPY    cbfs/fallback/bootblock.elf
>     LINK       cbfs/fallback/romstage.debug
>     OBJCOPY    bootblock.raw.bin
> Forbidden global variables in romstage:
> ffffff00 B val_sc_gp_lvl
>
> If i do not call setup_soc_gpios(), not occured the build error.
>
>
> Current status
> * 1. setup input mode to the target pin*
>     => can read the value from SC_GP_LVL register
>  *2. setup output mode to the target pin*
>     => When a write value to SC_GP_LVL register, successfully change the
> HIGH/LOW status of pin.
>     => But when a read the value from SC_GP_LVL register, can't read the
> value.
>
>
> My Goal is a create SW I2C port on my rangeley platform.
> Almost works is done. But just one is fail.
>
> Please advise to me.
>
> Thank you.
>
>
>
> 2016-07-18 오후 3:52에 Zoran Stojsavljevic 이(가) 쓴 글:
>
> > But DS is said to me that SC_GP_LVL is WR register.
>
> So, as I assumed, SC_GP_LVL is WR ONLY register. If it always works and
> puts out values, and retains them (which is another of mine assumption),
> the solution to RD problem is simplistic.
>
> Immediately after the: outl(GPIO, gpiobase + GPIO_SC_GP_LVL);
>
> Please, always remember the I/O data value you outl() into some heap
> global variable (which will always retain the latest outl() data value). If
> you need it back, read this variable.
>
> Best Regards,
> 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/20160719/605872b1/attachment.html>


More information about the coreboot mailing list