[coreboot] How to read the gpio status?

김유석 poplinux0 at gmail.com
Wed Jul 20 06:36:00 CEST 2016


Dear Sir.

Thank's your advise.

SW I2C is request of my client. to control special device.

And my customer are required to control at the romstage phase.

So, I try to find the solution of sw I2C on romstage.


But, if it is determined to be impossible, I'll be to convince customers.

Thank you.


2016-07-19 오후 6:42에 Zoran Stojsavljevic 이(가) 쓴 글:
> 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 
> <mailto:iederman 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 
> <mailto: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
>>>     <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/ccca5d59/attachment.html>


More information about the coreboot mailing list