blob: 64f2249d189eae0447406c0b0410128d2b05c6d4 [file] [log] [blame]
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2013-2019 IBM Corp. */
#include <skiboot.h>
#include <device.h>
#include <console.h>
#include <opal.h>
#include <libflash/ipmi-hiomap.h>
#include <libflash/mbox-flash.h>
#include <libflash/libflash.h>
#include <libflash/libffs.h>
#include <libflash/blocklevel.h>
#include <ast.h>
#include "astbmc.h"
enum ast_flash_style {
raw_flash,
raw_mem,
ipmi_hiomap,
mbox_hiomap,
};
static enum ast_flash_style ast_flash_get_fallback_style(void)
{
if (ast_lpc_fw_mbox_hiomap())
return mbox_hiomap;
if (ast_lpc_fw_maps_flash())
return raw_flash;
return raw_mem;
}
int pnor_init(void)
{
struct spi_flash_ctrl *pnor_ctrl = NULL;
struct blocklevel_device *bl = NULL;
enum ast_flash_style style;
int rc = 0;
if (ast_lpc_fw_ipmi_hiomap()) {
style = ipmi_hiomap;
rc = ipmi_hiomap_init(&bl);
}
if (!ast_lpc_fw_ipmi_hiomap() || rc) {
if (!ast_sio_is_enabled())
return -ENODEV;
style = ast_flash_get_fallback_style();
if (style == mbox_hiomap)
rc = mbox_flash_init(&bl);
else if (style == raw_flash)
rc = ast_sf_open(AST_SF_TYPE_PNOR, &pnor_ctrl);
else if (style == raw_mem)
rc = ast_sf_open(AST_SF_TYPE_MEM, &pnor_ctrl);
else {
prerror("Unhandled flash mode: %d\n", style);
return -ENODEV;
}
}
if (rc) {
prerror("PLAT: Failed to init PNOR driver\n");
goto fail;
}
if (style == raw_flash || style == raw_mem) {
rc = flash_init(pnor_ctrl, &bl, NULL);
if (rc)
goto fail;
}
rc = flash_register(bl);
if (!rc)
return 0;
fail:
if (bl) {
switch (style) {
case raw_flash:
case raw_mem:
flash_exit(bl);
break;
case ipmi_hiomap:
ipmi_hiomap_exit(bl);
break;
case mbox_hiomap:
mbox_flash_exit(bl);
break;
}
}
if (pnor_ctrl)
ast_sf_close(pnor_ctrl);
return rc;
}