source: trunk/ogp_spi.c @ 1475

Revision 1475, 3.8 KB checked in by hailfinger, 5 months ago (diff)

Have all programmer init functions register bus masters/programmers

All programmer types (Parallel, SPI, Opaque) now register themselves
into a generic programmer list and probing is now programmer-centric
instead of chip-centric.
Registering multiple SPI/... masters at the same time is now possible
without any problems. Handling multiple flash chips is still unchanged,
but now we have the infrastructure to deal with "dual BIOS" and "one
flash behind southbridge and one flash behind EC" sanely.

A nice side effect is that this patch kills quite a few global variables
and improves the situation for libflashrom.

Hint for developers:
struct {spi,par,opaque}_programmer now have a void *data pointer to
store any additional programmer-specific data, e.g. hardware
configuration info.

Note:
flashrom -f -c FOO -r forced_read.bin
does not work anymore. We have to find an architecturally clean way to
solve this.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@…>
Acked-by: Michael Karcher <flashrom@…>

Line 
1/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2010 Mark Marshall
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18 */
19
20#include <stdlib.h>
21#include <string.h>
22#include "flash.h"
23#include "programmer.h"
24
25#define PCI_VENDOR_ID_OGP 0x1227
26
27/* These are the register addresses for the OGD1 / OGA1.  If they are
28 * different for later versions of the hardware then we will need
29 * logic to select between the different hardware versions. */
30#define OGA1_XP10_BPROM_SI                           0x0040 /*  W */
31#define OGA1_XP10_BPROM_SO                           0x0040 /*  R */
32#define OGA1_XP10_BPROM_CE_BAR                       0x0044 /*  W */
33#define OGA1_XP10_BPROM_SCK                          0x0048 /*  W */
34#define OGA1_XP10_BPROM_REG_SEL                      0x004C /*  W */
35#define OGA1_XP10_CPROM_SI                           0x0050 /*  W */
36#define OGA1_XP10_CPROM_SO                           0x0050 /*  R */
37#define OGA1_XP10_CPROM_CE_BAR                       0x0054 /*  W */
38#define OGA1_XP10_CPROM_SCK                          0x0058 /*  W */
39#define OGA1_XP10_CPROM_REG_SEL                      0x005C /*  W */
40
41static uint8_t *ogp_spibar;
42
43static uint32_t ogp_reg_sel;
44static uint32_t ogp_reg_siso;
45static uint32_t ogp_reg__ce;
46static uint32_t ogp_reg_sck;
47
48const struct pcidev_status ogp_spi[] = {
49        {PCI_VENDOR_ID_OGP, 0x0000, OK, "Open Graphics Project", "Development Board OGD1"},
50        {},
51};
52
53static void ogp_request_spibus(void)
54{
55        pci_mmio_writel(1, ogp_spibar + ogp_reg_sel);
56}
57
58static void ogp_release_spibus(void)
59{
60        pci_mmio_writel(0, ogp_spibar + ogp_reg_sel);
61}
62
63static void ogp_bitbang_set_cs(int val)
64{
65        pci_mmio_writel(val, ogp_spibar + ogp_reg__ce);
66}
67
68static void ogp_bitbang_set_sck(int val)
69{
70        pci_mmio_writel(val, ogp_spibar + ogp_reg_sck);
71}
72
73static void ogp_bitbang_set_mosi(int val)
74{
75        pci_mmio_writel(val, ogp_spibar + ogp_reg_siso);
76}
77
78static int ogp_bitbang_get_miso(void)
79{
80        uint32_t tmp;
81
82        tmp = pci_mmio_readl(ogp_spibar + ogp_reg_siso);
83        return tmp & 0x1;
84}
85
86static const struct bitbang_spi_master bitbang_spi_master_ogp = {
87        .type = BITBANG_SPI_MASTER_OGP,
88        .set_cs = ogp_bitbang_set_cs,
89        .set_sck = ogp_bitbang_set_sck,
90        .set_mosi = ogp_bitbang_set_mosi,
91        .get_miso = ogp_bitbang_get_miso,
92        .request_bus = ogp_request_spibus,
93        .release_bus = ogp_release_spibus,
94        .half_period = 0,
95};
96
97static int ogp_spi_shutdown(void *data)
98{
99        physunmap(ogp_spibar, 4096);
100        pci_cleanup(pacc);
101        release_io_perms();
102
103        return 0;
104}
105
106int ogp_spi_init(void)
107{
108        char *type;
109
110        type = extract_programmer_param("rom");
111
112        if (!type) {
113                msg_perr("Please use flashrom -p ogp_spi:rom=... to specify "
114                         "which flashchip you want to access.\n");
115                return 1;
116        } else if (!strcasecmp(type, "bprom") || !strcasecmp(type, "bios")) {
117                ogp_reg_sel  = OGA1_XP10_BPROM_REG_SEL;
118                ogp_reg_siso = OGA1_XP10_BPROM_SI;
119                ogp_reg__ce  = OGA1_XP10_BPROM_CE_BAR;
120                ogp_reg_sck  = OGA1_XP10_BPROM_SCK;
121        } else if (!strcasecmp(type, "cprom") || !strcasecmp(type, "s3")) {
122                ogp_reg_sel  = OGA1_XP10_CPROM_REG_SEL;
123                ogp_reg_siso = OGA1_XP10_CPROM_SI;
124                ogp_reg__ce  = OGA1_XP10_CPROM_CE_BAR;
125                ogp_reg_sck  = OGA1_XP10_CPROM_SCK;
126        } else {
127                msg_perr("Invalid or missing rom= parameter.\n");
128                return 1;
129        }
130
131        get_io_perms();
132
133        io_base_addr = pcidev_init(PCI_BASE_ADDRESS_0, ogp_spi);
134
135        ogp_spibar = physmap("OGP registers", io_base_addr, 4096);
136
137        if (register_shutdown(ogp_spi_shutdown, NULL))
138                return 1;
139
140        if (bitbang_spi_init(&bitbang_spi_master_ogp))
141                return 1;
142
143        return 0;
144}
Note: See TracBrowser for help on using the repository browser.