uboot/drivers/pch/pch9.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2014 Google, Inc
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <log.h>
   9#include <pch.h>
  10
  11#define GPIO_BASE       0x48
  12#define IO_BASE         0x4c
  13#define SBASE_ADDR      0x54
  14
  15static int pch9_get_spi_base(struct udevice *dev, ulong *sbasep)
  16{
  17        uint32_t sbase_addr;
  18
  19        dm_pci_read_config32(dev, SBASE_ADDR, &sbase_addr);
  20        *sbasep = sbase_addr & 0xfffffe00;
  21
  22        return 0;
  23}
  24
  25static int pch9_get_gpio_base(struct udevice *dev, u32 *gbasep)
  26{
  27        u32 base;
  28
  29        /*
  30         * GPIO_BASE moved to its current offset with ICH6, but prior to
  31         * that it was unused (or undocumented). Check that it looks
  32         * okay: not all ones or zeros.
  33         *
  34         * Note we don't need check bit0 here, because the Tunnel Creek
  35         * GPIO base address register bit0 is reserved (read returns 0),
  36         * while on the Ivybridge the bit0 is used to indicate it is an
  37         * I/O space.
  38         */
  39        dm_pci_read_config32(dev, GPIO_BASE, &base);
  40        if (base == 0x00000000 || base == 0xffffffff) {
  41                debug("%s: unexpected BASE value\n", __func__);
  42                return -ENODEV;
  43        }
  44
  45        /*
  46         * Okay, I guess we're looking at the right device. The actual
  47         * GPIO registers are in the PCI device's I/O space, starting
  48         * at the offset that we just read. Bit 0 indicates that it's
  49         * an I/O address, not a memory address, so mask that off.
  50         */
  51        *gbasep = base & 1 ? base & ~3 : base & ~15;
  52
  53        return 0;
  54}
  55
  56static int pch9_get_io_base(struct udevice *dev, u32 *iobasep)
  57{
  58        u32 base;
  59
  60        dm_pci_read_config32(dev, IO_BASE, &base);
  61        if (base == 0x00000000 || base == 0xffffffff) {
  62                debug("%s: unexpected BASE value\n", __func__);
  63                return -ENODEV;
  64        }
  65
  66        *iobasep = base & 1 ? base & ~3 : base & ~15;
  67
  68        return 0;
  69}
  70
  71static const struct pch_ops pch9_ops = {
  72        .get_spi_base   = pch9_get_spi_base,
  73        .get_gpio_base  = pch9_get_gpio_base,
  74        .get_io_base    = pch9_get_io_base,
  75};
  76
  77static const struct udevice_id pch9_ids[] = {
  78        { .compatible = "intel,pch9" },
  79        { }
  80};
  81
  82U_BOOT_DRIVER(pch9_drv) = {
  83        .name           = "intel-pch9",
  84        .id             = UCLASS_PCH,
  85        .of_match       = pch9_ids,
  86        .ops            = &pch9_ops,
  87};
  88