rk3288_spi: Add SPI driver

This commit is contained in:
Vladimir Serbinenko 2017-05-09 08:42:14 +02:00
parent c4313c812d
commit b0b1b81a11
4 changed files with 108 additions and 2 deletions

View file

@ -162,6 +162,7 @@ kernel = {
arm_coreboot = bus/fdt.c; arm_coreboot = bus/fdt.c;
arm_coreboot = term/ps2.c; arm_coreboot = term/ps2.c;
arm_coreboot = term/arm/pl050.c; arm_coreboot = term/arm/pl050.c;
arm_coreboot = bus/spi/rk3288_spi.c;
arm_coreboot = commands/keylayouts.c; arm_coreboot = commands/keylayouts.c;
arm_coreboot = kern/arm/coreboot/dma.c; arm_coreboot = kern/arm/coreboot/dma.c;

View file

@ -0,0 +1,103 @@
/*
* GRUB -- GRand Unified Bootloader
*
* Copyright (C) 2012 Google Inc.
* Copyright (C) 2016 Free Software Foundation, Inc.
*
* This is based on depthcharge code.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/misc.h>
#include <grub/fdtbus.h>
#include <grub/machine/kernel.h>
static grub_err_t
spi_send (const struct grub_fdtbus_dev *dev, const void *data, grub_size_t sz)
{
const grub_uint8_t *ptr = data, *end = ptr + sz;
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
spi[2] = 0;
spi[1] = sz - 1;
spi[0] = ((1 << 18) | spi[0]) & ~(1 << 19);
spi[2] = 1;
while (ptr < end)
{
while (spi[9] & 2);
spi[256] = *ptr++;
}
while (spi[9] & 1);
return GRUB_ERR_NONE;
}
static grub_err_t
spi_receive (const struct grub_fdtbus_dev *dev, void *data, grub_size_t sz)
{
grub_uint8_t *ptr = data, *end = ptr + sz;
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
spi[2] = 0;
spi[1] = sz - 1;
spi[0] = ((1 << 19) | spi[0]) & ~(1 << 18);
spi[2] = 1;
while (ptr < end)
{
while (spi[9] & 8);
*ptr++ = spi[512];
}
while (spi[9] & 1);
return GRUB_ERR_NONE;
}
static grub_err_t
spi_start (const struct grub_fdtbus_dev *dev)
{
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
spi[3] = 1;
return GRUB_ERR_NONE;
}
static void
spi_stop (const struct grub_fdtbus_dev *dev)
{
volatile grub_uint32_t *spi = grub_fdtbus_map_reg (dev, 0, 0);
spi[3] = 0;
}
static grub_err_t
spi_attach(const struct grub_fdtbus_dev *dev)
{
if (!grub_fdtbus_is_mapping_valid (grub_fdtbus_map_reg (dev, 0, 0)))
return GRUB_ERR_IO;
return GRUB_ERR_NONE;
}
static struct grub_fdtbus_driver spi =
{
.compatible = "rockchip,rk3288-spi",
.attach = spi_attach,
.send = spi_send,
.receive = spi_receive,
.start = spi_start,
.stop = spi_stop,
};
void
grub_rk3288_spi_init (void)
{
grub_fdtbus_register (&spi);
}

View file

@ -132,6 +132,8 @@ grub_machine_init (void)
grub_fatal ("No DTB found"); grub_fatal ("No DTB found");
grub_fdtbus_init (dtb, dtb_size); grub_fdtbus_init (dtb, dtb_size);
grub_rk3288_spi_init ();
grub_machine_timer_init (); grub_machine_timer_init ();
grub_pl050_init (); grub_pl050_init ();
} }

View file

@ -34,8 +34,8 @@ struct grub_fdt_board
extern struct grub_fdt_board grub_fdt_boards[]; extern struct grub_fdt_board grub_fdt_boards[];
void grub_machine_timer_init (void); void grub_machine_timer_init (void);
void grub_pl050_init (void); void grub_pl050_init (void);
void void grub_cros_init (void);
grub_cros_init (void); void grub_rk3288_spi_init (void);
extern grub_addr_t EXPORT_VAR (start_of_ram); extern grub_addr_t EXPORT_VAR (start_of_ram);
#endif /* ! ASM_FILE */ #endif /* ! ASM_FILE */