blob: 380f2db5579f39e077351d1c18de226c595ea20d [file] [log] [blame]
Lee Leahyeef40eb2017-03-23 10:54:57 -07001/*
Martin Roth0443ac22019-08-30 21:29:41 -06002 * This file is part of the coreboot project.
Lee Leahyeef40eb2017-03-23 10:54:57 -07003 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but without any warranty; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
Lee Leahy48dbc662017-05-08 16:56:03 -070015#include <commonlib/sdhci.h>
Lee Leahyeef40eb2017-03-23 10:54:57 -070016#include <device/pci.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020017#include <device/pci_ops.h>
Bora Guvendik39363742018-03-08 16:21:12 -080018#include <stdint.h>
Elyes HAOUASa1e22b82019-03-18 22:49:36 +010019#include <string.h>
20
21#include "sd_mmc.h"
Lee Leahyeef40eb2017-03-23 10:54:57 -070022#include "storage.h"
Lee Leahyeef40eb2017-03-23 10:54:57 -070023
24/* Initialize an SDHCI port */
25int sdhci_controller_init(struct sdhci_ctrlr *sdhci_ctrlr, void *ioaddr)
26{
27 memset(sdhci_ctrlr, 0, sizeof(*sdhci_ctrlr));
28 sdhci_ctrlr->ioaddr = ioaddr;
29 return add_sdhci(sdhci_ctrlr);
30}
31
32struct sd_mmc_ctrlr *new_mem_sdhci_controller(void *ioaddr)
33{
Arthur Heymanseb501f02019-11-20 22:13:02 +010034 static bool sdhci_init_done;
35 static struct sdhci_ctrlr sdhci_ctrlr;
Lee Leahyeef40eb2017-03-23 10:54:57 -070036
Arthur Heymanseb501f02019-11-20 22:13:02 +010037 if (sdhci_init_done == true) {
Bora Guvendik39363742018-03-08 16:21:12 -080038 sdhc_error("Error: SDHCI is already initialized.\n");
Lee Leahyeef40eb2017-03-23 10:54:57 -070039 return NULL;
Lee Leahyeef40eb2017-03-23 10:54:57 -070040 }
Bora Guvendik39363742018-03-08 16:21:12 -080041
Arthur Heymanseb501f02019-11-20 22:13:02 +010042 if (sdhci_controller_init(&sdhci_ctrlr, ioaddr)) {
Bora Guvendik39363742018-03-08 16:21:12 -080043 sdhc_error("Error: SDHCI initialization failed.\n");
44 return NULL;
45 }
46
Arthur Heymanseb501f02019-11-20 22:13:02 +010047 sdhci_init_done = true;
Bora Guvendik39363742018-03-08 16:21:12 -080048
Arthur Heymanseb501f02019-11-20 22:13:02 +010049 return &sdhci_ctrlr.sd_mmc_ctrlr;
Lee Leahyeef40eb2017-03-23 10:54:57 -070050}
51
Kyösti Mälkkie0887212019-09-26 22:33:51 +030052struct sd_mmc_ctrlr *new_pci_sdhci_controller(pci_devfn_t dev)
Lee Leahyeef40eb2017-03-23 10:54:57 -070053{
54 uint32_t addr;
55
Kyösti Mälkkie0887212019-09-26 22:33:51 +030056 addr = pci_s_read_config32(dev, PCI_BASE_ADDRESS_0);
Lee Leahyeef40eb2017-03-23 10:54:57 -070057 if (addr == ((uint32_t)~0)) {
58 sdhc_error("Error: PCI SDHCI not found\n");
59 return NULL;
60 }
61
62 addr &= ~0xf;
63 return new_mem_sdhci_controller((void *)addr);
64}