soc/qualcomm/ipq40xx: Initial commit for IPQ40xx SoC support
Copy 'ipq806x' files as a template BUG=chrome-os-partner:49249 TEST=None. Initial code not sure if it will even compile BRANCH=none Original-Commit-Id: dc6a5937953fe61cd4b5a99ca49f9371c4b712d4 Original-Change-Id: If171fcdd3b0561cb6b7dab5f8434de7ef711ea41 Original-Signed-off-by: Varadarajan Narayanan <varada@codeaurora.org> Original-Signed-off-by: Kan Yan <kyan@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/333178 Original-Commit-Ready: David Hendricks <dhendrix@chromium.org> Original-Tested-by: David Hendricks <dhendrix@chromium.org> Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> squashed: soc/qualcomm/ipq40xx: Update ipq806x/storm references Since the files were taken from ipq806x/storm as template. Update those references to reflect ipq40xx/gale. BUG=chrome-os-partner:49249 TEST=None. Initial code not sure if it will even compile BRANCH=none Original-Commit-Id: c6c76d184cc92c09e6826fbdc7d7fac59b2cb69b Original-Change-Id: Ieae1bce25291243b4a6034d37a6949978f318997 Original-Signed-off-by: Varadarajan Narayanan <varada@codeaurora.org> Original-Reviewed-on: https://chromium-review.googlesource.com/333293 Original-Commit-Ready: David Hendricks <dhendrix@chromium.org> Original-Tested-by: David Hendricks <dhendrix@chromium.org> Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Change-Id: Ie5794c48131ae562861074b406106734541880d9 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Reviewed-on: https://review.coreboot.org/14644 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
parent
c84e2fe893
commit
a6935c2508
|
@ -0,0 +1,34 @@
|
|||
config SOC_QC_IPQ40XX
|
||||
bool
|
||||
default n
|
||||
select ARCH_BOOTBLOCK_ARMV7
|
||||
select ARCH_VERSTAGE_ARMV7
|
||||
select ARCH_ROMSTAGE_ARMV7
|
||||
select ARCH_RAMSTAGE_ARMV7
|
||||
select BOOTBLOCK_CONSOLE
|
||||
select HAVE_UART_SPECIAL
|
||||
select SPI_ATOMIC_SEQUENCING
|
||||
select GENERIC_GPIO_LIB
|
||||
|
||||
if SOC_QC_IPQ40XX
|
||||
|
||||
config CHROMEOS
|
||||
select CHROMEOS_VBNV_FLASH
|
||||
select SEPARATE_VERSTAGE
|
||||
select RETURN_FROM_VERSTAGE
|
||||
|
||||
config MBN_ENCAPSULATION
|
||||
depends on USE_BLOBS
|
||||
bool "bootblock encapsulation for ipq40xx"
|
||||
default y
|
||||
|
||||
config SBL_BLOB
|
||||
depends on USE_BLOBS
|
||||
string "file name of the Qualcomm SBL blob"
|
||||
default "3rdparty/blobs/cpu/qualcomm/ipq40xx/uber-sbl.mbn"
|
||||
help
|
||||
The path and filename of the binary blob containing
|
||||
ipq40xx early initialization code, as supplied by the
|
||||
vendor.
|
||||
|
||||
endif
|
|
@ -0,0 +1,84 @@
|
|||
##
|
||||
## This file is part of the coreboot project.
|
||||
##
|
||||
## Copyright 2014 Google Inc.
|
||||
##
|
||||
## This program 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; version 2 of the License.
|
||||
##
|
||||
## This program 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.
|
||||
##
|
||||
|
||||
ifeq ($(CONFIG_SOC_QC_IPQ40XX),y)
|
||||
|
||||
bootblock-y += clock.c
|
||||
bootblock-y += gpio.c
|
||||
bootblock-$(CONFIG_SPI_FLASH) += spi.c
|
||||
bootblock-y += timer.c
|
||||
bootblock-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
|
||||
verstage-y += clock.c
|
||||
verstage-y += gpio.c
|
||||
libverstage-y += gsbi.c
|
||||
libverstage-y += i2c.c
|
||||
libverstage-y += qup.c
|
||||
libverstage-y += spi.c
|
||||
verstage-y += timer.c
|
||||
verstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
|
||||
romstage-y += clock.c
|
||||
romstage-y += blobs_init.c
|
||||
romstage-y += gpio.c
|
||||
romstage-$(CONFIG_SPI_FLASH) += spi.c
|
||||
romstage-y += timer.c
|
||||
romstage-$(CONFIG_DRIVERS_UART) += uart.c
|
||||
romstage-y += cbmem.c
|
||||
|
||||
ramstage-y += blobs_init.c
|
||||
ramstage-y += cbmem.c
|
||||
ramstage-y += clock.c
|
||||
ramstage-y += gpio.c
|
||||
ramstage-y += lcc.c
|
||||
ramstage-y += soc.c
|
||||
ramstage-$(CONFIG_SPI_FLASH) += spi.c
|
||||
ramstage-y += timer.c
|
||||
ramstage-y += uart.c # Want the UART always ready for the kernels' earlyprintk
|
||||
ramstage-y += usb.c
|
||||
ramstage-y += tz_wrapper.S
|
||||
|
||||
ifeq ($(CONFIG_USE_BLOBS),y)
|
||||
|
||||
# Add MBN header to allow SBL3 to start coreboot bootblock
|
||||
$(objcbfs)/bootblock.mbn: $(objcbfs)/bootblock.raw.bin
|
||||
@printf " ADD MBN $(subst $(obj)/,,$(@))\n"
|
||||
./util/ipqheader/ipqheader.py $(call loadaddr,bootblock) $< $@.tmp
|
||||
@mv $@.tmp $@
|
||||
|
||||
# Create a complete bootblock which will start up the system
|
||||
$(objcbfs)/bootblock.bin: $(call strip_quotes,$(CONFIG_SBL_BLOB)) \
|
||||
$(objcbfs)/bootblock.mbn
|
||||
@printf " MBNCAT $(subst $(obj)/,,$(@))\n"
|
||||
@util/ipqheader/mbncat.py -o $@.tmp $^
|
||||
@mv $@.tmp $@
|
||||
|
||||
endif
|
||||
|
||||
CPPFLAGS_common += -Isrc/soc/qualcomm/ipq40xx/include
|
||||
|
||||
# List of binary blobs coreboot needs in CBFS to be able to boot up this SOC
|
||||
mbn-files := cdt.mbn ddr.mbn rpm.mbn tz.mbn
|
||||
|
||||
# Location of the binary blobs
|
||||
mbn-root := 3rdparty/blobs/cpu/qualcomm/ipq40xx
|
||||
|
||||
# Create make variables to aid cbfs-files-handler in processing the blobs (add
|
||||
# them all as raw binaries at the root level).
|
||||
$(foreach f,$(mbn-files),$(eval cbfs-files-y += $(f))\
|
||||
$(eval $(f)-file := $(mbn-root)/$(f))\
|
||||
$(eval $(f)-type := raw))
|
||||
|
||||
endif
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2014 Google Inc.
|
||||
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program 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; version 2 of the License.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#include <arch/cache.h>
|
||||
#include <arch/io.h>
|
||||
#include <cbfs.h>
|
||||
#include <console/console.h>
|
||||
#include <string.h>
|
||||
#include <timer.h>
|
||||
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/soc_services.h>
|
||||
|
||||
#include "mbn_header.h"
|
||||
|
||||
static void *load_ipq_blob(const char *file_name)
|
||||
{
|
||||
struct mbn_header *blob_mbn;
|
||||
void *blob_dest;
|
||||
size_t blob_size;
|
||||
|
||||
blob_mbn = cbfs_boot_map_with_leak(file_name, CBFS_TYPE_RAW,
|
||||
&blob_size);
|
||||
if (!blob_mbn)
|
||||
return NULL;
|
||||
|
||||
/* some sanity checks on the headers */
|
||||
if ((blob_mbn->mbn_version != 3) ||
|
||||
(blob_mbn->mbn_total_size > blob_size))
|
||||
return NULL;
|
||||
|
||||
blob_dest = (void *) blob_mbn->mbn_destination;
|
||||
if (blob_mbn->mbn_destination) {
|
||||
/* Copy the blob to the appropriate memory location. */
|
||||
memcpy(blob_dest, blob_mbn + 1, blob_mbn->mbn_total_size);
|
||||
cache_sync_instructions();
|
||||
return blob_dest;
|
||||
}
|
||||
|
||||
/*
|
||||
* The blob did not have to be relocated, return its address in CBFS
|
||||
* cache.
|
||||
*/
|
||||
return blob_mbn + 1;
|
||||
}
|
||||
|
||||
#ifdef __PRE_RAM__
|
||||
|
||||
#define DDR_VERSION() ((const char *)0x2a03f600)
|
||||
#define MAX_DDR_VERSION_SIZE 48
|
||||
|
||||
int initialize_dram(void)
|
||||
{
|
||||
void *cdt;
|
||||
int (*ddr_init_function)(void *cdt_header);
|
||||
|
||||
cdt = load_ipq_blob("cdt.mbn");
|
||||
ddr_init_function = load_ipq_blob("ddr.mbn");
|
||||
|
||||
if (!cdt || !ddr_init_function) {
|
||||
printk(BIOS_ERR, "cdt: %p, ddr_init_function: %p\n",
|
||||
cdt, ddr_init_function);
|
||||
die("could not find DDR initialization blobs\n");
|
||||
}
|
||||
|
||||
if (ddr_init_function(cdt) < 0)
|
||||
die("Fail to Initialize DDR\n");
|
||||
|
||||
/*
|
||||
* Once DDR initializer finished, its verison can be found at a fixed
|
||||
* address in SRAM.
|
||||
*/
|
||||
printk(BIOS_INFO, "DDR version %.*s initialized\n",
|
||||
MAX_DDR_VERSION_SIZE, DDR_VERSION());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* __PRE_RAM__ */
|
||||
|
||||
void start_tzbsp(void)
|
||||
{
|
||||
void *tzbsp = load_ipq_blob("tz.mbn");
|
||||
|
||||
if (!tzbsp)
|
||||
die("could not find or map TZBSP\n");
|
||||
|
||||
printk(BIOS_INFO, "Starting TZBSP\n");
|
||||
|
||||
tz_init_wrapper(0, 0, tzbsp);
|
||||
}
|
||||
|
||||
/* RPM version is encoded in a 32 bit word at the fixed address */
|
||||
#define RPM_VERSION() (*((u32 *)(0x00108008)))
|
||||
void start_rpm(void)
|
||||
{
|
||||
u32 load_addr;
|
||||
u32 ready_mask = 1 << 10;
|
||||
u32 rpm_version;
|
||||
|
||||
struct stopwatch sw;
|
||||
|
||||
if (read32(RPM_SIGNAL_COOKIE) == RPM_FW_MAGIC_NUM) {
|
||||
printk(BIOS_INFO, "RPM appears to have already started\n");
|
||||
return;
|
||||
}
|
||||
|
||||
load_addr = (u32) load_ipq_blob("rpm.mbn");
|
||||
if (!load_addr)
|
||||
die("could not find or map RPM code\n");
|
||||
|
||||
printk(BIOS_INFO, "Starting RPM\n");
|
||||
|
||||
/* Clear 'ready' indication. */
|
||||
/*
|
||||
* RPM_INT_ACK is clear-on-write type register,
|
||||
* read-modify-write is not recommended.
|
||||
*/
|
||||
write32(RPM_INT_ACK, ready_mask);
|
||||
|
||||
/* Set RPM entry address */
|
||||
write32(RPM_SIGNAL_ENTRY, load_addr);
|
||||
/* Set cookie */
|
||||
write32(RPM_SIGNAL_COOKIE, RPM_FW_MAGIC_NUM);
|
||||
|
||||
/* Wait for RPM start indication, up to 100ms. */
|
||||
stopwatch_init_usecs_expire(&sw, 100000);
|
||||
while (!(read32(RPM_INT) & ready_mask))
|
||||
if (stopwatch_expired(&sw))
|
||||
die("RPM Initialization failed\n");
|
||||
|
||||
/* Acknowledge RPM initialization */
|
||||
write32(RPM_INT_ACK, ready_mask);
|
||||
|
||||
/* Report RPM version, it is encoded in a 32 bit value. */
|
||||
rpm_version = RPM_VERSION();
|
||||
printk(BIOS_INFO, "Started RPM version %d.%d.%d\n",
|
||||
rpm_version >> 24,
|
||||
(rpm_version >> 16) & 0xff,
|
||||
rpm_version & 0xffff);
|
||||
}
|
||||
#endif /* !__PRE_RAM__ */
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* This program 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; version 2 of the License.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#include <cbmem.h>
|
||||
#include <soc/soc_services.h>
|
||||
|
||||
void *cbmem_top(void)
|
||||
{
|
||||
return _memlayout_cbmem_top;
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <delay.h>
|
||||
#include <soc/clock.h>
|
||||
#include <types.h>
|
||||
|
||||
/**
|
||||
* uart_pll_vote_clk_enable - enables PLL8
|
||||
*/
|
||||
void uart_pll_vote_clk_enable(unsigned int clk_dummy)
|
||||
{
|
||||
setbits_le32(BB_PLL_ENA_SC0_REG, BIT(8));
|
||||
|
||||
if (!clk_dummy)
|
||||
while ((read32(PLL_LOCK_DET_STATUS_REG) & BIT(8)) == 0)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* uart_set_rate_mnd - configures divider M and D values
|
||||
*
|
||||
* Sets the M, D parameters of the divider to generate the GSBI UART
|
||||
* apps clock.
|
||||
*/
|
||||
static void uart_set_rate_mnd(unsigned int gsbi_port, unsigned int m,
|
||||
unsigned int n)
|
||||
{
|
||||
/* Assert MND reset. */
|
||||
setbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(7));
|
||||
/* Program M and D values. */
|
||||
write32(GSBIn_UART_APPS_MD_REG(gsbi_port), MD16(m, n));
|
||||
/* Deassert MND reset. */
|
||||
clrbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(7));
|
||||
}
|
||||
|
||||
/**
|
||||
* uart_branch_clk_enable_reg - enables branch clock
|
||||
*
|
||||
* Enables branch clock for GSBI UART port.
|
||||
*/
|
||||
static void uart_branch_clk_enable_reg(unsigned int gsbi_port)
|
||||
{
|
||||
setbits_le32(GSBIn_UART_APPS_NS_REG(gsbi_port), BIT(9));
|
||||
}
|
||||
|
||||
/**
|
||||
* uart_local_clock_enable - configures N value and enables root clocks
|
||||
*
|
||||
* Sets the N parameter of the divider and enables root clock and
|
||||
* branch clocks for GSBI UART port.
|
||||
*/
|
||||
static void uart_local_clock_enable(unsigned int gsbi_port, unsigned int n,
|
||||
unsigned int m)
|
||||
{
|
||||
unsigned int reg_val, uart_ns_val;
|
||||
void *const reg = (void *)GSBIn_UART_APPS_NS_REG(gsbi_port);
|
||||
|
||||
/*
|
||||
* Program the NS register, if applicable. NS registers are not
|
||||
* set in the set_rate path because power can be saved by deferring
|
||||
* the selection of a clocked source until the clock is enabled.
|
||||
*/
|
||||
reg_val = read32(reg); // REG(0x29D4+(0x20*((n)-1)))
|
||||
reg_val &= ~(Uart_clk_ns_mask);
|
||||
uart_ns_val = NS(BIT_POS_31, BIT_POS_16, n, m, 5, 4, 3, 1, 2, 0, 3);
|
||||
reg_val |= (uart_ns_val & Uart_clk_ns_mask);
|
||||
write32(reg, reg_val);
|
||||
|
||||
/* enable MNCNTR_EN */
|
||||
reg_val = read32(reg);
|
||||
reg_val |= BIT(8);
|
||||
write32(reg, reg_val);
|
||||
|
||||
/* set source to PLL8 running @384MHz */
|
||||
reg_val = read32(reg);
|
||||
reg_val |= 0x3;
|
||||
write32(reg, reg_val);
|
||||
|
||||
/* Enable root. */
|
||||
reg_val |= Uart_en_mask;
|
||||
write32(reg, reg_val);
|
||||
uart_branch_clk_enable_reg(gsbi_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* uart_set_gsbi_clk - enables HCLK for UART GSBI port
|
||||
*/
|
||||
static void uart_set_gsbi_clk(unsigned int gsbi_port)
|
||||
{
|
||||
setbits_le32(GSBIn_HCLK_CTL_REG(gsbi_port), BIT(4));
|
||||
}
|
||||
|
||||
/**
|
||||
* uart_clock_config - configures UART clocks
|
||||
*
|
||||
* Configures GSBI UART dividers, enable root and branch clocks.
|
||||
*/
|
||||
void uart_clock_config(unsigned int gsbi_port, unsigned int m,
|
||||
unsigned int n, unsigned int d, unsigned int clk_dummy)
|
||||
{
|
||||
uart_set_rate_mnd(gsbi_port, m, d);
|
||||
uart_pll_vote_clk_enable(clk_dummy);
|
||||
uart_local_clock_enable(gsbi_port, n, m);
|
||||
uart_set_gsbi_clk(gsbi_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* nand_clock_config - configure NAND controller clocks
|
||||
*
|
||||
* Enable clocks to EBI2. Must be invoked before touching EBI2
|
||||
* registers.
|
||||
*/
|
||||
void nand_clock_config(void)
|
||||
{
|
||||
write32(EBI2_CLK_CTL_REG,
|
||||
CLK_BRANCH_ENA(1) | ALWAYS_ON_CLK_BRANCH_ENA(1));
|
||||
|
||||
/* Wait for clock to stabilize. */
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_clock_config - configure USB controller clocks and reset the controller
|
||||
*/
|
||||
void usb_clock_config(void)
|
||||
{
|
||||
/* Magic clock initialization numbers, nobody knows how they work... */
|
||||
write32(USB30_MASTER_CLK_CTL_REG, 0x10);
|
||||
write32(USB30_1_MASTER_CLK_CTL_REG, 0x10);
|
||||
write32(USB30_MASTER_CLK_MD, 0x500DF);
|
||||
write32(USB30_MASTER_CLK_NS, 0xE40942);
|
||||
write32(USB30_MOC_UTMI_CLK_MD, 0x100D7);
|
||||
write32(USB30_MOC_UTMI_CLK_NS, 0xD80942);
|
||||
write32(USB30_MOC_UTMI_CLK_CTL, 0x10);
|
||||
write32(USB30_1_MOC_UTMI_CLK_CTL, 0x10);
|
||||
|
||||
write32(USB30_RESET,
|
||||
1 << 5 | /* assert port2 HS PHY async reset */
|
||||
1 << 4 | /* assert master async reset */
|
||||
1 << 3 | /* assert sleep async reset */
|
||||
1 << 2 | /* assert MOC UTMI async reset */
|
||||
1 << 1 | /* assert power-on async reset */
|
||||
1 << 0); /* assert PHY async reset */
|
||||
udelay(5);
|
||||
write32(USB30_RESET, 0); /* deassert all USB resets again */
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <gpio.h>
|
||||
#include <soc/iomap.h>
|
||||
|
||||
/*******************************************************
|
||||
Function description: check for invalid GPIO #
|
||||
Arguments :
|
||||
gpio_t gpio - Gpio number
|
||||
|
||||
Return : GPIO Valid(0)/Invalid(1)
|
||||
*******************************************************/
|
||||
|
||||
static inline int gpio_not_valid(gpio_t gpio)
|
||||
{
|
||||
return (gpio > GPIO_MAX_NUM);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************
|
||||
Function description: configure GPIO functinality
|
||||
Arguments :
|
||||
gpio_t gpio - Gpio number
|
||||
unsigned func - Functionality number
|
||||
unsigned pull - pull up/down, no pull range(0-3)
|
||||
unsigned drvstr - range (0 - 7)-> (2- 16)MA steps of 2
|
||||
unsigned enable - 0 Disable, 1 - Enable.
|
||||
|
||||
Return : None
|
||||
*******************************************************/
|
||||
|
||||
|
||||
void gpio_tlmm_config_set(gpio_t gpio, unsigned func,
|
||||
unsigned pull, unsigned drvstr,
|
||||
unsigned enable)
|
||||
{
|
||||
unsigned val = 0;
|
||||
|
||||
if (gpio_not_valid(gpio))
|
||||
return;
|
||||
|
||||
val |= (pull & GPIO_CFG_PULL_MASK) << GPIO_CFG_PULL_SHIFT;
|
||||
val |= (func & GPIO_CFG_FUNC_MASK) << GPIO_CFG_FUNC_SHIFT;
|
||||
val |= (drvstr & GPIO_CFG_DRV_MASK) << GPIO_CFG_DRV_SHIFT;
|
||||
val |= (enable & GPIO_CFG_OE_MASK) << GPIO_CFG_OE_SHIFT;
|
||||
|
||||
write32(GPIO_CONFIG_ADDR(gpio), val);
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
Function description: Get GPIO configuration
|
||||
Arguments :
|
||||
gpio_t gpio - Gpio number
|
||||
unsigned *func - Functionality number
|
||||
unsigned *pull - pull up/down, no pull range(0-3)
|
||||
unsigned *drvstr - range (0 - 7)-> (2- 16)MA steps of 2
|
||||
unsigned *enable - 0 - Disable, 1- Enable.
|
||||
|
||||
Return : None
|
||||
*******************************************************/
|
||||
|
||||
|
||||
void gpio_tlmm_config_get(gpio_t gpio, unsigned *func,
|
||||
unsigned *pull, unsigned *drvstr,
|
||||
unsigned *enable)
|
||||
{
|
||||
unsigned val;
|
||||
void *addr = GPIO_CONFIG_ADDR(gpio);
|
||||
|
||||
if (gpio_not_valid(gpio))
|
||||
return;
|
||||
|
||||
val = read32(addr);
|
||||
|
||||
*pull = (val >> GPIO_CFG_PULL_SHIFT) & GPIO_CFG_PULL_MASK;
|
||||
*func = (val >> GPIO_CFG_FUNC_SHIFT) & GPIO_CFG_FUNC_MASK;
|
||||
*drvstr = (val >> GPIO_CFG_DRV_SHIFT) & GPIO_CFG_DRV_MASK;
|
||||
*enable = (val >> GPIO_CFG_OE_SHIFT) & GPIO_CFG_OE_MASK;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
Function description: get GPIO IO functinality details
|
||||
Arguments :
|
||||
gpio_t gpio - Gpio number
|
||||
unsigned *in - Value of GPIO input
|
||||
unsigned *out - Value of GPIO output
|
||||
|
||||
Return : None
|
||||
*******************************************************/
|
||||
int gpio_get(gpio_t gpio)
|
||||
{
|
||||
if (gpio_not_valid(gpio))
|
||||
return -1;
|
||||
|
||||
|
||||
return (read32(GPIO_IN_OUT_ADDR(gpio)) >> GPIO_IO_IN_SHIFT) &
|
||||
GPIO_IO_IN_MASK;
|
||||
}
|
||||
|
||||
void gpio_set(gpio_t gpio, int value)
|
||||
{
|
||||
if (gpio_not_valid(gpio))
|
||||
return;
|
||||
|
||||
write32(GPIO_IN_OUT_ADDR(gpio), (value & 1) << GPIO_IO_OUT_SHIFT);
|
||||
}
|
||||
|
||||
void gpio_input_pulldown(gpio_t gpio)
|
||||
{
|
||||
gpio_tlmm_config_set(gpio, GPIO_FUNC_DISABLE,
|
||||
GPIO_PULL_DOWN, GPIO_2MA, GPIO_DISABLE);
|
||||
}
|
||||
|
||||
void gpio_input_pullup(gpio_t gpio)
|
||||
{
|
||||
gpio_tlmm_config_set(gpio, GPIO_FUNC_DISABLE,
|
||||
GPIO_PULL_UP, GPIO_2MA, GPIO_DISABLE);
|
||||
}
|
||||
|
||||
void gpio_input(gpio_t gpio)
|
||||
{
|
||||
gpio_tlmm_config_set(gpio, GPIO_FUNC_DISABLE,
|
||||
GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE);
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 - 2015 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/gsbi.h>
|
||||
#include <console/console.h>
|
||||
|
||||
static inline void *gsbi_ctl_reg_addr(gsbi_id_t gsbi_id)
|
||||
{
|
||||
switch (gsbi_id) {
|
||||
case GSBI_ID_1:
|
||||
return GSBI1_CTL_REG;
|
||||
case GSBI_ID_2:
|
||||
return GSBI2_CTL_REG;
|
||||
case GSBI_ID_3:
|
||||
return GSBI3_CTL_REG;
|
||||
case GSBI_ID_4:
|
||||
return GSBI4_CTL_REG;
|
||||
case GSBI_ID_5:
|
||||
return GSBI5_CTL_REG;
|
||||
case GSBI_ID_6:
|
||||
return GSBI6_CTL_REG;
|
||||
case GSBI_ID_7:
|
||||
return GSBI7_CTL_REG;
|
||||
default:
|
||||
printk(BIOS_ERR, "Unsupported GSBI%d\n", gsbi_id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
gsbi_return_t gsbi_init(gsbi_id_t gsbi_id, gsbi_protocol_t protocol)
|
||||
{
|
||||
unsigned reg_val;
|
||||
unsigned m = 1;
|
||||
unsigned n = 4;
|
||||
unsigned pre_div = 4;
|
||||
unsigned src = 3;
|
||||
unsigned mnctr_mode = 2;
|
||||
void *gsbi_ctl = gsbi_ctl_reg_addr(gsbi_id);
|
||||
|
||||
if (!gsbi_ctl)
|
||||
return GSBI_ID_ERROR;
|
||||
|
||||
write32(GSBI_HCLK_CTL(gsbi_id),
|
||||
(1 << GSBI_HCLK_CTL_GATE_ENA) |
|
||||
(1 << GSBI_HCLK_CTL_BRANCH_ENA));
|
||||
|
||||
if (gsbi_init_board(gsbi_id))
|
||||
return GSBI_UNSUPPORTED;
|
||||
|
||||
write32(GSBI_QUP_APSS_NS_REG(gsbi_id), 0);
|
||||
write32(GSBI_QUP_APSS_MD_REG(gsbi_id), 0);
|
||||
|
||||
reg_val = ((m & GSBI_QUP_APPS_M_MASK) << GSBI_QUP_APPS_M_SHFT) |
|
||||
((~n & GSBI_QUP_APPS_D_MASK) << GSBI_QUP_APPS_D_SHFT);
|
||||
write32(GSBI_QUP_APSS_MD_REG(gsbi_id), reg_val);
|
||||
|
||||
reg_val = (((~(n - m)) & GSBI_QUP_APPS_N_MASK) <<
|
||||
GSBI_QUP_APPS_N_SHFT) |
|
||||
((mnctr_mode & GSBI_QUP_APPS_MNCTR_MODE_MSK) <<
|
||||
GSBI_QUP_APPS_MNCTR_MODE_SFT) |
|
||||
(((pre_div - 1) & GSBI_QUP_APPS_PRE_DIV_MSK) <<
|
||||
GSBI_QUP_APPS_PRE_DIV_SFT) |
|
||||
(src & GSBI_QUP_APPS_SRC_SEL_MSK);
|
||||
write32(GSBI_QUP_APSS_NS_REG(gsbi_id), reg_val);
|
||||
|
||||
reg_val |= (1 << GSBI_QUP_APPS_ROOT_ENA_SFT) |
|
||||
(1 << GSBI_QUP_APPS_MNCTR_EN_SFT);
|
||||
write32(GSBI_QUP_APSS_NS_REG(gsbi_id), reg_val);
|
||||
|
||||
reg_val |= (1 << GSBI_QUP_APPS_BRANCH_ENA_SFT);
|
||||
write32(GSBI_QUP_APSS_NS_REG(gsbi_id), reg_val);
|
||||
|
||||
/*Select i2c protocol*/
|
||||
write32(gsbi_ctl,
|
||||
((GSBI_CTL_PROTO_I2C & GSBI_CTL_PROTO_CODE_MSK)
|
||||
<< GSBI_CTL_PROTO_CODE_SFT));
|
||||
|
||||
return GSBI_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 - 2015 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <assert.h>
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <device/i2c.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <soc/gsbi.h>
|
||||
#include <soc/qup.h>
|
||||
|
||||
static qup_config_t gsbi1_qup_config = {
|
||||
QUP_MINICORE_I2C_MASTER,
|
||||
100000,
|
||||
24000000,
|
||||
QUP_MODE_FIFO,
|
||||
0
|
||||
};
|
||||
|
||||
static qup_config_t gsbi4_qup_config = {
|
||||
QUP_MINICORE_I2C_MASTER,
|
||||
100000,
|
||||
24000000,
|
||||
QUP_MODE_FIFO,
|
||||
0
|
||||
};
|
||||
|
||||
static qup_config_t gsbi7_qup_config = {
|
||||
QUP_MINICORE_I2C_MASTER,
|
||||
100000,
|
||||
24000000,
|
||||
QUP_MODE_FIFO,
|
||||
0
|
||||
};
|
||||
|
||||
static int i2c_read(uint32_t gsbi_id, uint8_t slave,
|
||||
uint8_t *data, int data_len)
|
||||
{
|
||||
qup_data_t obj;
|
||||
qup_return_t qup_ret = 0;
|
||||
|
||||
memset(&obj, 0, sizeof(obj));
|
||||
obj.protocol = QUP_MINICORE_I2C_MASTER;
|
||||
obj.p.iic.addr = slave;
|
||||
obj.p.iic.data_len = data_len;
|
||||
obj.p.iic.data = data;
|
||||
qup_ret = qup_recv_data(gsbi_id, &obj);
|
||||
|
||||
if (QUP_SUCCESS != qup_ret)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_write(uint32_t gsbi_id, uint8_t slave,
|
||||
uint8_t *data, int data_len, uint8_t stop_seq)
|
||||
{
|
||||
qup_data_t obj;
|
||||
qup_return_t qup_ret = 0;
|
||||
|
||||
memset(&obj, 0, sizeof(obj));
|
||||
obj.protocol = QUP_MINICORE_I2C_MASTER;
|
||||
obj.p.iic.addr = slave;
|
||||
obj.p.iic.data_len = data_len;
|
||||
obj.p.iic.data = data;
|
||||
qup_ret = qup_send_data(gsbi_id, &obj, stop_seq);
|
||||
|
||||
if (QUP_SUCCESS != qup_ret)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_init(unsigned bus)
|
||||
{
|
||||
unsigned gsbi_id = bus;
|
||||
qup_config_t *qup_config;
|
||||
|
||||
switch (gsbi_id) {
|
||||
case GSBI_ID_1:
|
||||
qup_config = &gsbi1_qup_config;
|
||||
break;
|
||||
case GSBI_ID_4:
|
||||
qup_config = &gsbi4_qup_config;
|
||||
break;
|
||||
case GSBI_ID_7:
|
||||
qup_config = &gsbi7_qup_config;
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_ERR, "QUP configuration not defind for GSBI%d.\n",
|
||||
gsbi_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (qup_config->initialized)
|
||||
return 0;
|
||||
|
||||
if (gsbi_init(gsbi_id, GSBI_PROTO_I2C_ONLY)) {
|
||||
printk(BIOS_ERR, "failed to initialize gsbi\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (qup_init(gsbi_id, qup_config)) {
|
||||
printk(BIOS_ERR, "failed to initialize qup\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (qup_reset_i2c_master_status(gsbi_id)) {
|
||||
printk(BIOS_ERR, "failed to reset i2c master status\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
qup_config->initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int platform_i2c_transfer(unsigned bus, struct i2c_seg *segments, int seg_count)
|
||||
{
|
||||
struct i2c_seg *seg = segments;
|
||||
int ret = 0;
|
||||
|
||||
if (i2c_init(bus))
|
||||
return 1;
|
||||
|
||||
while (!ret && seg_count--) {
|
||||
if (seg->read)
|
||||
ret = i2c_read(bus, seg->chip, seg->buf, seg->len);
|
||||
else
|
||||
ret = i2c_write(bus, seg->chip, seg->buf, seg->len,
|
||||
(seg_count ? 0 : 1));
|
||||
seg++;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
qup_set_state(bus, QUP_STATE_RESET);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (c) 2012 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _IPQ40XX_CDP_H_
|
||||
#define _IPQ40XX_CDP_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
unsigned smem_get_board_machtype(void);
|
||||
|
||||
typedef enum {
|
||||
PHY_INTERFACE_MODE_MII,
|
||||
PHY_INTERFACE_MODE_GMII,
|
||||
PHY_INTERFACE_MODE_SGMII,
|
||||
PHY_INTERFACE_MODE_QSGMII,
|
||||
PHY_INTERFACE_MODE_TBI,
|
||||
PHY_INTERFACE_MODE_RMII,
|
||||
PHY_INTERFACE_MODE_RGMII,
|
||||
PHY_INTERFACE_MODE_RGMII_ID,
|
||||
PHY_INTERFACE_MODE_RGMII_RXID,
|
||||
PHY_INTERFACE_MODE_RGMII_TXID,
|
||||
PHY_INTERFACE_MODE_RTBI,
|
||||
PHY_INTERFACE_MODE_XGMII,
|
||||
PHY_INTERFACE_MODE_NONE /* Must be last */
|
||||
} phy_interface_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int gpio;
|
||||
unsigned int func;
|
||||
unsigned int dir;
|
||||
unsigned int pull;
|
||||
unsigned int drvstr;
|
||||
unsigned int enable;
|
||||
} gpio_func_data_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int m_value;
|
||||
unsigned int n_value;
|
||||
unsigned int d_value;
|
||||
} uart_clk_mnd_t;
|
||||
|
||||
/* SPI Mode */
|
||||
|
||||
typedef enum {
|
||||
NOR_SPI_MODE_0,
|
||||
NOR_SPI_MODE_1,
|
||||
NOR_SPI_MODE_2,
|
||||
NOR_SPI_MODE_3,
|
||||
} spi_mode;
|
||||
|
||||
/* SPI GSBI Bus number */
|
||||
|
||||
typedef enum {
|
||||
GSBI_BUS_5 = 0,
|
||||
GSBI_BUS_6,
|
||||
GSBI_BUS_7,
|
||||
} spi_gsbi_bus_num;
|
||||
|
||||
/* SPI Chip selects */
|
||||
|
||||
typedef enum {
|
||||
SPI_CS_0 ,
|
||||
SPI_CS_1,
|
||||
SPI_CS_2,
|
||||
SPI_CS_3,
|
||||
} spi_cs;
|
||||
|
||||
/* Flash Types */
|
||||
|
||||
typedef enum {
|
||||
ONLY_NAND,
|
||||
ONLY_NOR,
|
||||
NAND_NOR,
|
||||
NOR_MMC,
|
||||
} flash_desc;
|
||||
|
||||
#define NO_OF_DBG_UART_GPIOS 2
|
||||
|
||||
#define SPI_NOR_FLASH_VENDOR_MICRON 0x1
|
||||
#define SPI_NOR_FLASH_VENDOR_SPANSION 0x2
|
||||
|
||||
/* SPI parameters */
|
||||
|
||||
typedef struct {
|
||||
spi_mode mode;
|
||||
spi_gsbi_bus_num bus_number;
|
||||
spi_cs chip_select;
|
||||
int vendor;
|
||||
} spinorflash_params_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned count;
|
||||
uint8_t addr[7];
|
||||
} ipq_gmac_phy_addr_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned base;
|
||||
int unit;
|
||||
unsigned is_macsec;
|
||||
unsigned mac_pwr0;
|
||||
unsigned mac_pwr1;
|
||||
unsigned mac_conn_to_phy;
|
||||
phy_interface_t phy;
|
||||
ipq_gmac_phy_addr_t phy_addr;
|
||||
} ipq_gmac_board_cfg_t;
|
||||
|
||||
#define IPQ_GMAC_NMACS 4
|
||||
|
||||
enum gale_board_id {
|
||||
BOARD_ID_PROTO_0 = 0,
|
||||
BOARD_ID_PROTO_0_2 = 1,
|
||||
BOARD_ID_WHIRLWIND = 2,
|
||||
BOARD_ID_WHIRLWIND_SP5 = 3,
|
||||
BOARD_ID_PROTO_0_2_NAND = 26,
|
||||
};
|
||||
|
||||
/* Board specific parameters */
|
||||
typedef struct {
|
||||
#if 0
|
||||
unsigned int gmac_gpio_count;
|
||||
gpio_func_data_t *gmac_gpio;
|
||||
ipq_gmac_board_cfg_t gmac_cfg[IPQ_GMAC_NMACS];
|
||||
flash_desc flashdesc;
|
||||
spinorflash_params_t flash_param;
|
||||
#endif
|
||||
} __attribute__ ((__packed__)) board_ipq40xx_params_t;
|
||||
|
||||
extern board_ipq40xx_params_t *gboard_param;
|
||||
|
||||
#if 0
|
||||
static inline int gmac_cfg_is_valid(ipq_gmac_board_cfg_t *cfg)
|
||||
{
|
||||
/*
|
||||
* 'cfg' is valid if and only if
|
||||
* unit number is non-negative and less than IPQ_GMAC_NMACS.
|
||||
* 'cfg' pointer lies within the array range of
|
||||
* board_ipq40xx_params_t->gmac_cfg[]
|
||||
*/
|
||||
return ((cfg >= &gboard_param->gmac_cfg[0]) &&
|
||||
(cfg < &gboard_param->gmac_cfg[IPQ_GMAC_NMACS]) &&
|
||||
(cfg->unit >= 0) && (cfg->unit < IPQ_GMAC_NMACS));
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int get_board_index(unsigned machid);
|
||||
void ipq_configure_gpio(const gpio_func_data_t *gpio, unsigned count);
|
||||
|
||||
void board_nand_init(void);
|
||||
|
||||
#endif /* _IPQ40XX_CDP_H_ */
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
|
||||
* Source : APQ8064 LK Boot
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __IPQ40XX_CLOCK_H_
|
||||
#define __IPQ40XX_CLOCK_H_
|
||||
|
||||
#include <soc/iomap.h>
|
||||
|
||||
/* UART clock @ 7.3728 MHz */
|
||||
#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
|
||||
|
||||
/* UART specific definitions */
|
||||
|
||||
#define Uart_ns_val NS(BIT_POS_31, BIT_POS_16, N_VALUE, M_VALUE, \
|
||||
5, 4, 3, 1, 2, 0, 3)
|
||||
#define Uart_clk_ns_mask (BM(BIT_POS_31, BIT_POS_16) | \
|
||||
BM(BIT_POS_6, BIT_POS_0))
|
||||
#define Uart_mnd_en_mask (BIT(8) * !!(625))
|
||||
#define Uart_en_mask BIT(11)
|
||||
#define MD16(m, n) (BVAL(BIT_POS_31, BIT_POS_16, m) | \
|
||||
BVAL(BIT_POS_15, BIT_POS_0, ~(n)))
|
||||
#define Uart_ns_val_rumi NS(BIT_POS_31, BIT_POS_16, N_VALUE, M_VALUE, \
|
||||
5, 4, 3, 1, 2, 0, 0)
|
||||
#define GSBIn_UART_APPS_MD_REG(n) REG(0x29D0+(0x20*((n)-1)))
|
||||
#define GSBIn_UART_APPS_NS_REG(n) REG(0x29D4+(0x20*((n)-1)))
|
||||
#define GSBIn_HCLK_CTL_REG(n) REG(0x29C0+(0x20*((n)-1)))
|
||||
#define BB_PLL_ENA_SC0_REG REG(0x34C0)
|
||||
#define BB_PLL8_STATUS_REG REG(0x3158)
|
||||
#define REG(off) ((void *)(MSM_CLK_CTL_BASE + (off)))
|
||||
#define PLL8_STATUS_BIT 16
|
||||
|
||||
#define PLL_LOCK_DET_STATUS_REG REG(0x03420)
|
||||
#define SFAB_AHB_S3_FCLK_CTL_REG REG(0x0216C)
|
||||
#define CFPB_CLK_NS_REG REG(0x0264C)
|
||||
#define CFPB0_HCLK_CTL_REG REG(0x02650)
|
||||
#define SFAB_CFPB_S_HCLK_CTL_REG REG(0x026C0)
|
||||
#define CFPB_SPLITTER_HCLK_CTL_REG REG(0x026E0)
|
||||
#define EBI2_CLK_CTL_REG REG(0x03B00)
|
||||
|
||||
#define USB30_MASTER_CLK_CTL_REG REG(0x3b24)
|
||||
#define USB30_MASTER_CLK_MD REG(0x3b28)
|
||||
#define USB30_MASTER_CLK_NS REG(0x3b2c)
|
||||
#define USB30_1_MASTER_CLK_CTL_REG REG(0x3b34)
|
||||
#define USB30_MOC_UTMI_CLK_MD REG(0x3b40)
|
||||
#define USB30_MOC_UTMI_CLK_NS REG(0x3b44)
|
||||
#define USB30_MOC_UTMI_CLK_CTL REG(0x3b48)
|
||||
#define USB30_1_MOC_UTMI_CLK_CTL REG(0x3b4c)
|
||||
#define USB30_RESET REG(0x3b50)
|
||||
|
||||
#define ALWAYS_ON_CLK_BRANCH_ENA(i) ((i) << 8)
|
||||
|
||||
#define CLK_BRANCH_ENA_MASK 0x00000010
|
||||
#define CLK_BRANCH_ENA_ENABLE 0x00000010
|
||||
#define CLK_BRANCH_ENA_DISABLE 0x00000000
|
||||
#define CLK_BRANCH_ENA(i) ((i) << 4)
|
||||
|
||||
/* Register: CFPB_CLK_NS */
|
||||
#define CLK_DIV_MASK 0x00000003
|
||||
#define CLK_DIV_DIV_1 0x00000000
|
||||
#define CLK_DIV_DIV_2 0x00000001
|
||||
#define CLK_DIV_DIV_3 0x00000002
|
||||
#define CLK_DIV_DIV_4 0x00000003
|
||||
#define CLK_DIV(i) ((i) << 0)
|
||||
|
||||
#define MN_MODE_DUAL_EDGE 0x2
|
||||
#define BIT_POS_31 31
|
||||
#define BIT_POS_16 16
|
||||
#define BIT_POS_6 6
|
||||
#define BIT_POS_0 0
|
||||
#define BIT_POS_15 15
|
||||
|
||||
#define BM(m, l) (((((unsigned int)-1) << (31-m)) >> (31-m+l)) << l)
|
||||
#define BVAL(m, l, val) (((val) << l) & BM(m, l))
|
||||
|
||||
/* MD Registers */
|
||||
#define MD4(m_lsb, m, n_lsb, n) \
|
||||
(BVAL((m_lsb+3), m_lsb, m) | BVAL((n_lsb+3), n_lsb, ~(n)))
|
||||
|
||||
#define MD8(m_lsb, m, n_lsb, n) \
|
||||
(BVAL((m_lsb+7), m_lsb, m) | BVAL((n_lsb+7), n_lsb, ~(n)))
|
||||
|
||||
/* NS Registers */
|
||||
#define NS(n_msb, n_lsb, n, m, mde_lsb, d_msb, d_lsb, d, s_msb, s_lsb, s) \
|
||||
(BVAL(n_msb, n_lsb, ~(n-m)) \
|
||||
| (BVAL((mde_lsb+1), mde_lsb, MN_MODE_DUAL_EDGE) * !!(n)) \
|
||||
| BVAL(d_msb, d_lsb, (d-1)) | BVAL(s_msb, s_lsb, s))
|
||||
|
||||
#define NS_MM(n_msb, n_lsb, n, m, d_msb, d_lsb, d, s_msb, s_lsb, s) \
|
||||
(BVAL(n_msb, n_lsb, ~(n-m)) | BVAL(d_msb, d_lsb, (d-1)) \
|
||||
| BVAL(s_msb, s_lsb, s))
|
||||
|
||||
#define NS_DIVSRC(d_msb , d_lsb, d, s_msb, s_lsb, s) \
|
||||
(BVAL(d_msb, d_lsb, (d-1)) | BVAL(s_msb, s_lsb, s))
|
||||
|
||||
#define NS_DIV(d_msb , d_lsb, d) \
|
||||
BVAL(d_msb, d_lsb, (d-1))
|
||||
|
||||
#define NS_SRC_SEL(s_msb, s_lsb, s) \
|
||||
BVAL(s_msb, s_lsb, s)
|
||||
|
||||
#define GMAC_AHB_RESET 0x903E24
|
||||
|
||||
#define SRC_SEL_PLL0 (0x2 << 0)
|
||||
#define MNCNTR_MODE_DUAL_EDGE (0x2 << 5)
|
||||
#define MNCNTR_ENABLE (0x1 << 8)
|
||||
#define MNCNTR_RST_ACTIVE (0x1 << 7)
|
||||
#define N_VAL 15
|
||||
|
||||
#define GMAC_CORE_RESET(n) \
|
||||
((void *)(0x903CBC + ((n) * 0x20)))
|
||||
|
||||
#define GMACSEC_CORE_RESET(n) \
|
||||
((void *)(0x903E28 + ((n - 1) * 4)))
|
||||
|
||||
#define GMAC_COREn_CLCK_SRC_CTL(N) \
|
||||
(0x00900000 + (0x3CA0 + (32*(N-1))))
|
||||
|
||||
#define GMAC_COREn_CLCK_SRC0_MD(N) \
|
||||
(0x00900000 + (0x3CA4 + (32*(N-1))))
|
||||
|
||||
#define GMAC_COREn_CLCK_SRC1_MD(N) \
|
||||
(0x00900000 + (0x3CA8 + (32*(N-1))))
|
||||
|
||||
#define GMAC_COREn_CLCK_SRC0_NS(N) \
|
||||
(0x00900000 + (0x3CAC + (32*(N-1))))
|
||||
|
||||
#define GMAC_COREn_CLCK_SRC1_NS(N) \
|
||||
(0x00900000 + (0x3CB0 + (32*(N-1))))
|
||||
|
||||
#define DISABLE_DUAL_MN8_SEL (0)
|
||||
#define DISABLE_CLK_LOW_PWR (0 << 2)
|
||||
#define GMAC_CORE_CLCK_ROOT_ENABLE (1 << 1)
|
||||
|
||||
/* GMAC_COREn_CLK_SRC[0,1]_MD register bits (Assuming 133MHz) */
|
||||
#define GMAC_CORE_CLCK_M 0x32
|
||||
#define GMAC_CORE_CLCK_D 0 /* NOT(2*D) value */
|
||||
#define GMAC_CORE_CLCK_M_SHIFT 16
|
||||
#define GMAC_CORE_CLCK_D_SHIFT 0
|
||||
#define GMAC_CORE_CLCK_M_VAL \
|
||||
(GMAC_CORE_CLCK_M << GMAC_CORE_CLCK_M_SHIFT)
|
||||
#define GMAC_CORE_CLCK_D_VAL \
|
||||
(GMAC_CORE_CLCK_D << GMAC_CORE_CLCK_D_SHIFT)
|
||||
|
||||
/* GMAC_COREn_CLK_SRC[0,1]_NS register bits (Assuming 133MHz) */
|
||||
#define GMAC_CORE_CLCK_N 0x4 /* NOT(N-M) value, N=301 */
|
||||
#define GMAC_CORE_CLCK_N_SHIFT 16
|
||||
#define GMAC_CORE_CLCK_N_VAL \
|
||||
(GMAC_CORE_CLCK_N << GMAC_CORE_CLCK_N_SHIFT)
|
||||
/* Enable M/N counter */
|
||||
#define GMAC_CORE_CLCK_MNCNTR_EN 0x00000100
|
||||
/* Activate reset for M/N counter */
|
||||
#define GMAC_CORE_CLCK_MNCNTR_RST 0x00000080
|
||||
/* M/N counter mode mask */
|
||||
#define GMAC_CORE_CLCK_MNCNTR_MODE_MASK 0x00000060
|
||||
#define GMAC_CORE_CLCK_MNCNTR_MODE_SHIFT 5
|
||||
/* M/N counter mode dual-edge */
|
||||
#define GMAC_CORE_CLCK_MNCNTR_MODE_DUAL \
|
||||
(2 << GMAC_CORE_CLCK_MNCNTR_MODE_SHIFT)
|
||||
/* Pre divider select mask */
|
||||
#define GMAC_CORE_CLCK_PRE_DIV_SEL_MASK 0x00000018
|
||||
#define GMAC_CORE_CLCK_PRE_DIV_SEL_SHIFT 3
|
||||
/* Pre divider bypass */
|
||||
#define GMAC_CORE_CLCK_PRE_DIV_SEL_BYP \
|
||||
(0 << GMAC_CORE_CLCK_PRE_DIV_SEL_SHIFT)
|
||||
/* clk source Mux select mask */
|
||||
#define GMAC_CORE_CLCK_SRC_SEL_MASK 0x00000007
|
||||
#define GMAC_CORE_CLCK_SRC_SEL_SHIFT 0
|
||||
/* output of clk source Mux is PLL0 */
|
||||
#define GMAC_CORE_CLCK_SRC_SEL_PLL0 \
|
||||
(2 << GMAC_CORE_CLCK_SRC_SEL_SHIFT)
|
||||
#define GMAC_COREn_CLCK_CTL(N) \
|
||||
(0x00900000 + (0x3CB4 + (32*(N-1))))
|
||||
|
||||
#define GMAC_COREn_CLCK_INV_DISABLE (0 << 5)
|
||||
#define GMAC_COREn_CLCK_BRANCH_ENA (1 << 4)
|
||||
|
||||
|
||||
/* Uart specific clock settings */
|
||||
|
||||
void uart_pll_vote_clk_enable(unsigned int);
|
||||
void uart_clock_config(unsigned int gsbi_port, unsigned int m, unsigned int n,
|
||||
unsigned int d, unsigned int clk_dummy);
|
||||
void nand_clock_config(void);
|
||||
void usb_clock_config(void);
|
||||
int audio_clock_config(unsigned frequency);
|
||||
|
||||
#endif /* __PLATFORM_IPQ40XX_CLOCK_H_ */
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2012 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Taken from U-Boot.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __SOC_QUALCOMM_IPQ40XX_EBI2_H_
|
||||
#define __SOC_QUALCOMM_IPQ40XX_EBI2_H_
|
||||
|
||||
#define EBI2CR_BASE (0x1A600000)
|
||||
|
||||
struct ebi2cr_regs {
|
||||
uint32_t chip_select_cfg0; /* 0x00000000 */
|
||||
uint32_t cfg; /* 0x00000004 */
|
||||
uint32_t hw_info; /* 0x00000008 */
|
||||
uint8_t reserved0[20];
|
||||
uint32_t lcd_cfg0; /* 0x00000020 */
|
||||
uint32_t lcd_cfg1; /* 0x00000024 */
|
||||
uint8_t reserved1[8];
|
||||
uint32_t arbiter_cfg; /* 0x00000030 */
|
||||
uint8_t reserved2[28];
|
||||
uint32_t debug_sel; /* 0x00000050 */
|
||||
uint32_t crc_cfg; /* 0x00000054 */
|
||||
uint32_t crc_reminder_cfg; /* 0x00000058 */
|
||||
uint32_t nand_adm_mux; /* 0x0000005C */
|
||||
uint32_t mutex_addr_offset; /* 0x00000060 */
|
||||
uint32_t misr_value; /* 0x00000064 */
|
||||
uint32_t clkon_cfg; /* 0x00000068 */
|
||||
uint32_t core_clkon_cfg; /* 0x0000006C */
|
||||
};
|
||||
|
||||
/* Register: EBI2_CHIP_SELECT_CFG0 */
|
||||
#define CS7_CFG_MASK 0x00001000
|
||||
#define CS7_CFG_DISABLE 0x00000000
|
||||
#define CS7_CFG_GENERAL_SRAM_MEMORY_INTERFACE 0x00001000
|
||||
#define CS7_CFG(i) ((i) << 12)
|
||||
|
||||
#define CS6_CFG_MASK 0x00000800
|
||||
#define CS6_CFG_DISABLE 0x00000000
|
||||
#define CS6_CFG_GENERAL_SRAM_MEMORY_INTERFACE 0x00000800
|
||||
#define CS6_CFG(i) ((i) << 11)
|
||||
|
||||
#define ETM_CS_CFG_MASK 0x00000400
|
||||
#define ETM_CS_CFG_DISABLE 0x00000000
|
||||
#define ETM_CS_CFG_GENERAL_SRAM_MEMORY_INTERFACE 0x00000400
|
||||
#define ETM_CS_CFG(i) ((i) << 10)
|
||||
|
||||
#define CS5_CFG_MASK 0x00000300
|
||||
#define CS5_CFG_DISABLE 0x00000000
|
||||
#define CS5_CFG_LCD_DEVICE_CONNECTED 0x00000100
|
||||
#define CS5_CFG_LCD_DEVICE_CHIP_ENABLE 0x00000200
|
||||
#define CS5_CFG_GENERAL_SRAM_MEMORY_INTERFACE 0x00000300
|
||||
#define CS5_CFG(i) ((i) << 8)
|
||||
|
||||
#define CS4_CFG_MASK 0x000000c0
|
||||
#define CS4_CFG_DISABLE 0x00000000
|
||||
#define CS4_CFG_LCD_DEVICE_CONNECTED 0x00000040
|
||||
#define CS4_CFG_GENERAL_SRAM_MEMORY_INTERFACE 0x000000C0
|
||||
#define CS4_CFG(i) ((i) << 6)
|
||||
|
||||
#define CS3_CFG_MASK 0x00000020
|
||||
#define CS3_CFG_DISABLE 0x00000000
|
||||
#define CS3_CFG_GENERAL_SRAM_MEMORY_INTERFACE 0x00000020
|
||||
#define CS3_CFG(i) ((i) << 5)
|
||||
|
||||
#define CS2_CFG_MASK 0x00000010
|
||||
#define CS2_CFG_DISABLE 0x00000000
|
||||
#define CS2_CFG_GENERAL_SRAM_MEMORY_INTERFACE 0x00000010
|
||||
#define CS2_CFG(i) ((i) << 4)
|
||||
|
||||
#define CS1_CFG_MASK 0x0000000c
|
||||
#define CS1_CFG_DISABLE 0x00000000
|
||||
#define CS1_CFG_SERIAL_FLASH_DEVICE 0x00000004
|
||||
#define CS1_CFG_GENERAL_SRAM_MEMORY_INTERFACE 0x00000008
|
||||
#define CS1_CFG(i) ((i) << 2)
|
||||
|
||||
#define CS0_CFG_MASK 0x00000003
|
||||
#define CS0_CFG_DISABLE 0x00000000
|
||||
#define CS0_CFG_SERIAL_FLASH_DEVICE 0x00000001
|
||||
#define CS0_CFG_GENERAL_SRAM_MEMORY_INTERFACE 0x00000002
|
||||
#define CS0_CFG(i) ((i) << 0)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2012 The Linux Foundation. All rights reserved.
|
||||
* Source : APQ8064 LK Boot
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_QUALCOMM_IPQ40XX_GPIO_H_
|
||||
#define __SOC_QUALCOMM_IPQ40XX_GPIO_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define GPIO_FUNC_ENABLE 1
|
||||
#define GPIO_FUNC_DISABLE 0
|
||||
#define FUNC_SEL_1 1
|
||||
#define FUNC_SEL_3 3
|
||||
#define FUNC_SEL_GPIO 0
|
||||
#define GPIO_DRV_STR_10MA 0x4
|
||||
#define GPIO_DRV_STR_11MA 0x7
|
||||
|
||||
/* GPIO TLMM: Direction */
|
||||
#define GPIO_INPUT 0
|
||||
#define GPIO_OUTPUT 1
|
||||
|
||||
/* GPIO TLMM: Pullup/Pulldown */
|
||||
#define GPIO_NO_PULL 0
|
||||
#define GPIO_PULL_DOWN 1
|
||||
#define GPIO_KEEPER 2
|
||||
#define GPIO_PULL_UP 3
|
||||
|
||||
/* GPIO TLMM: Drive Strength */
|
||||
#define GPIO_2MA 0
|
||||
#define GPIO_4MA 1
|
||||
#define GPIO_6MA 2
|
||||
#define GPIO_8MA 3
|
||||
#define GPIO_10MA 4
|
||||
#define GPIO_12MA 5
|
||||
#define GPIO_14MA 6
|
||||
#define GPIO_16MA 7
|
||||
|
||||
/* GPIO TLMM: Status */
|
||||
#define GPIO_DISABLE 0
|
||||
#define GPIO_ENABLE 1
|
||||
|
||||
/* GPIO MAX Valid # */
|
||||
#define GPIO_MAX_NUM 68
|
||||
|
||||
/* GPIO TLMM: Mask */
|
||||
#define GPIO_CFG_PULL_MASK 0x3
|
||||
#define GPIO_CFG_FUNC_MASK 0xF
|
||||
#define GPIO_CFG_DRV_MASK 0x7
|
||||
#define GPIO_CFG_OE_MASK 0x1
|
||||
|
||||
/* GPIO TLMM: Shift */
|
||||
#define GPIO_CFG_PULL_SHIFT 0
|
||||
#define GPIO_CFG_FUNC_SHIFT 2
|
||||
#define GPIO_CFG_DRV_SHIFT 6
|
||||
#define GPIO_CFG_OE_SHIFT 9
|
||||
|
||||
/* GPIO IO: Mask */
|
||||
#define GPIO_IO_IN_MASK 0x1
|
||||
#define GPIO_IO_OUT_MASK 0x1
|
||||
|
||||
/* GPIO IO: Shift */
|
||||
#define GPIO_IO_IN_SHIFT 0
|
||||
#define GPIO_IO_OUT_SHIFT 1
|
||||
|
||||
typedef u32 gpio_t;
|
||||
|
||||
void gpio_tlmm_config_set(gpio_t gpio, unsigned int func,
|
||||
unsigned int pull, unsigned int drvstr,
|
||||
unsigned int enable);
|
||||
|
||||
void gpio_tlmm_config_get(gpio_t gpio, unsigned int *func,
|
||||
unsigned int *pull, unsigned int *drvstr,
|
||||
unsigned int *enable);
|
||||
|
||||
void gpio_io_config_set(gpio_t gpio, unsigned int out);
|
||||
|
||||
/* Keep this to maintain backwards compatibility with the vendor API. */
|
||||
static inline void gpio_tlmm_config(unsigned int gpio, unsigned int func,
|
||||
unsigned int dir, unsigned int pull,
|
||||
unsigned int drvstr, unsigned int enable)
|
||||
{
|
||||
gpio_tlmm_config_set(gpio, func, pull, drvstr, enable);
|
||||
}
|
||||
#endif // __SOC_QUALCOMM_IPQ40XX_GPIO_H_
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GSBI_H_
|
||||
#define __GSBI_H_
|
||||
|
||||
/* GSBI Registers */
|
||||
#define GSBI_CTRL_REG(base) ((base) + 0x0)
|
||||
|
||||
#define GSBI_CTRL_REG_PROTOCOL_CODE_S 4
|
||||
#define GSBI_PROTOCOL_CODE_I2C 0x2
|
||||
#define GSBI_PROTOCOL_CODE_SPI 0x3
|
||||
#define GSBI_PROTOCOL_CODE_UART_FLOW 0x4
|
||||
#define GSBI_PROTOCOL_CODE_I2C_UART 0x6
|
||||
|
||||
#define GSBI_HCLK_CTL_S 4
|
||||
#define GSBI_HCLK_CTL_CLK_ENA 0x1
|
||||
|
||||
typedef enum {
|
||||
GSBI_ID_1 = 1,
|
||||
GSBI_ID_2,
|
||||
GSBI_ID_3,
|
||||
GSBI_ID_4,
|
||||
GSBI_ID_5,
|
||||
GSBI_ID_6,
|
||||
GSBI_ID_7,
|
||||
} gsbi_id_t;
|
||||
|
||||
typedef enum {
|
||||
GSBI_SUCCESS = 0,
|
||||
GSBI_ID_ERROR,
|
||||
GSBI_ERROR,
|
||||
GSBI_UNSUPPORTED
|
||||
} gsbi_return_t;
|
||||
|
||||
typedef enum {
|
||||
GSBI_PROTO_I2C_UIM = 1,
|
||||
GSBI_PROTO_I2C_ONLY,
|
||||
GSBI_PROTO_SPI_ONLY,
|
||||
GSBI_PROTO_UART_FLOW_CTL,
|
||||
GSBI_PROTO_UIM,
|
||||
GSBI_PROTO_I2C_UART,
|
||||
} gsbi_protocol_t;
|
||||
|
||||
gsbi_return_t gsbi_init(gsbi_id_t gsbi_id, gsbi_protocol_t protocol);
|
||||
int gsbi_init_board(gsbi_id_t gsbi_id);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (c) 2012 - 2013, 2015 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2008, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google, Inc. nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_QUALCOMM_IPQ40XX_IOMAP_H_
|
||||
#define __SOC_QUALCOMM_IPQ40XX_IOMAP_H_
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <soc/cdp.h>
|
||||
|
||||
/* Typecast to allow integers being passed as address
|
||||
This needs to be included because vendor code is not compliant with our
|
||||
macros for read/write. Hence, special macros for readl_i and writel_i are
|
||||
included to do this in one place for all occurrences in vendor code
|
||||
*/
|
||||
#define readl_i(a) read32((const void *)(a))
|
||||
#define writel_i(v,a) write32((void *)a, v)
|
||||
#define clrsetbits_le32_i(addr, clear, set) \
|
||||
clrsetbits_le32(((void *)(addr)), (clear), (set))
|
||||
|
||||
#define MSM_CLK_CTL_BASE ((void *)0x00900000)
|
||||
|
||||
#define MSM_TMR_BASE ((void *)0x0200A000)
|
||||
#define MSM_GPT_BASE (MSM_TMR_BASE + 0x04)
|
||||
#define MSM_DGT_BASE (MSM_TMR_BASE + 0x24)
|
||||
|
||||
#define GPT_REG(off) (MSM_GPT_BASE + (off))
|
||||
#define DGT_REG(off) (MSM_DGT_BASE + (off))
|
||||
|
||||
#define APCS_WDT0_EN (MSM_TMR_BASE + 0x0040)
|
||||
#define APCS_WDT0_RST (MSM_TMR_BASE + 0x0038)
|
||||
#define APCS_WDT0_BARK_TIME (MSM_TMR_BASE + 0x004C)
|
||||
#define APCS_WDT0_BITE_TIME (MSM_TMR_BASE + 0x005C)
|
||||
|
||||
#define APCS_WDT0_CPU0_WDOG_EXPIRED_ENABLE (MSM_CLK_CTL_BASE + 0x3820)
|
||||
|
||||
#define GPT_MATCH_VAL GPT_REG(0x0000)
|
||||
#define GPT_COUNT_VAL GPT_REG(0x0004)
|
||||
#define GPT_ENABLE GPT_REG(0x0008)
|
||||
#define GPT_CLEAR GPT_REG(0x000C)
|
||||
|
||||
#define GPT1_MATCH_VAL GPT_REG(0x00010)
|
||||
#define GPT1_COUNT_VAL GPT_REG(0x00014)
|
||||
#define GPT1_ENABLE GPT_REG(0x00018)
|
||||
#define GPT1_CLEAR GPT_REG(0x0001C)
|
||||
|
||||
#define DGT_MATCH_VAL DGT_REG(0x0000)
|
||||
#define DGT_COUNT_VAL DGT_REG(0x0004)
|
||||
#define DGT_ENABLE DGT_REG(0x0008)
|
||||
#define DGT_CLEAR DGT_REG(0x000C)
|
||||
#define DGT_CLK_CTL DGT_REG(0x0010)
|
||||
|
||||
/* RPM interface constants */
|
||||
#define RPM_INT ((void *)0x63020)
|
||||
#define RPM_INT_ACK ((void *)0x63060)
|
||||
#define RPM_SIGNAL_COOKIE ((void *)0x47C20)
|
||||
#define RPM_SIGNAL_ENTRY ((void *)0x47C24)
|
||||
#define RPM_FW_MAGIC_NUM 0x4D505242
|
||||
|
||||
#define TLMM_BASE_ADDR ((void *)0x00800000)
|
||||
#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
|
||||
#define GPIO_IN_OUT_ADDR(x) (GPIO_CONFIG_ADDR(x) + 4)
|
||||
|
||||
/* Yes, this is not a typo... host2 is actually mapped before host1. */
|
||||
#define USB_HOST2_XHCI_BASE 0x10000000
|
||||
#define USB_HOST2_DWC3_BASE 0x1000C100
|
||||
#define USB_HOST2_PHY_BASE 0x100F8800
|
||||
#define USB_HOST1_XHCI_BASE 0x11000000
|
||||
#define USB_HOST1_DWC3_BASE 0x1100C100
|
||||
#define USB_HOST1_PHY_BASE 0x110F8800
|
||||
|
||||
#define GSBI_4 4
|
||||
#define UART1_DM_BASE 0x12450000
|
||||
#define UART_GSBI1_BASE 0x12440000
|
||||
#define UART2_DM_BASE 0x12490000
|
||||
#define UART_GSBI2_BASE 0x12480000
|
||||
#define UART4_DM_BASE 0x16340000
|
||||
#define UART_GSBI4_BASE 0x16300000
|
||||
|
||||
#define UART2_DM_BASE 0x12490000
|
||||
#define UART_GSBI2_BASE 0x12480000
|
||||
|
||||
#define GSBI1_BASE ((void *)0x12440000)
|
||||
#define GSBI2_BASE ((void *)0x12480000)
|
||||
#define GSBI3_BASE ((void *)0x16200000)
|
||||
#define GSBI4_BASE ((void *)0x16300000)
|
||||
#define GSBI5_BASE ((void *)0x1A200000)
|
||||
#define GSBI6_BASE ((void *)0x16500000)
|
||||
#define GSBI7_BASE ((void *)0x16600000)
|
||||
|
||||
#define GSBI1_CTL_REG (GSBI1_BASE + (0x0))
|
||||
#define GSBI2_CTL_REG (GSBI2_BASE + (0x0))
|
||||
#define GSBI3_CTL_REG (GSBI3_BASE + (0x0))
|
||||
#define GSBI4_CTL_REG (GSBI4_BASE + (0x0))
|
||||
#define GSBI5_CTL_REG (GSBI5_BASE + (0x0))
|
||||
#define GSBI6_CTL_REG (GSBI6_BASE + (0x0))
|
||||
#define GSBI7_CTL_REG (GSBI7_BASE + (0x0))
|
||||
|
||||
#define GSBI_QUP1_BASE (GSBI1_BASE + 0x20000)
|
||||
#define GSBI_QUP2_BASE (GSBI2_BASE + 0x20000)
|
||||
#define GSBI_QUP3_BASE (GSBI3_BASE + 0x80000)
|
||||
#define GSBI_QUP4_BASE (GSBI4_BASE + 0x80000)
|
||||
#define GSBI_QUP5_BASE (GSBI5_BASE + 0x80000)
|
||||
#define GSBI_QUP6_BASE (GSBI6_BASE + 0x80000)
|
||||
#define GSBI_QUP7_BASE (GSBI7_BASE + 0x80000)
|
||||
|
||||
#define GSBI_CTL_PROTO_I2C 2
|
||||
#define GSBI_CTL_PROTO_CODE_SFT 4
|
||||
#define GSBI_CTL_PROTO_CODE_MSK 0x7
|
||||
#define GSBI_HCLK_CTL_GATE_ENA 6
|
||||
#define GSBI_HCLK_CTL_BRANCH_ENA 4
|
||||
#define GSBI_QUP_APPS_M_SHFT 16
|
||||
#define GSBI_QUP_APPS_M_MASK 0xFF
|
||||
#define GSBI_QUP_APPS_D_SHFT 0
|
||||
#define GSBI_QUP_APPS_D_MASK 0xFF
|
||||
#define GSBI_QUP_APPS_N_SHFT 16
|
||||
#define GSBI_QUP_APPS_N_MASK 0xFF
|
||||
#define GSBI_QUP_APPS_ROOT_ENA_SFT 11
|
||||
#define GSBI_QUP_APPS_BRANCH_ENA_SFT 9
|
||||
#define GSBI_QUP_APPS_MNCTR_EN_SFT 8
|
||||
#define GSBI_QUP_APPS_MNCTR_MODE_MSK 0x3
|
||||
#define GSBI_QUP_APPS_MNCTR_MODE_SFT 5
|
||||
#define GSBI_QUP_APPS_PRE_DIV_MSK 0x3
|
||||
#define GSBI_QUP_APPS_PRE_DIV_SFT 3
|
||||
#define GSBI_QUP_APPS_SRC_SEL_MSK 0x7
|
||||
|
||||
|
||||
#define GSBI_QUP_APSS_MD_REG(gsbi_n) ((MSM_CLK_CTL_BASE + 0x29c8) + \
|
||||
(32*(gsbi_n-1)))
|
||||
#define GSBI_QUP_APSS_NS_REG(gsbi_n) ((MSM_CLK_CTL_BASE + 0x29cc) + \
|
||||
(32*(gsbi_n-1)))
|
||||
#define GSBI_HCLK_CTL(n) ((MSM_CLK_CTL_BASE + 0x29C0) + \
|
||||
(32*(n-1)))
|
||||
#endif // __SOC_QUALCOMM_IPQ40XX_IOMAP_H_
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define TIMER_LOAD_VAL 0x21
|
||||
|
||||
#define GPT_ENABLE_CLR_ON_MATCH_EN 2
|
||||
#define GPT_ENABLE_EN 1
|
||||
#define DGT_ENABLE_CLR_ON_MATCH_EN 2
|
||||
#define DGT_ENABLE_EN 1
|
||||
|
||||
#define SPSS_TIMER_STATUS_DGT_EN (1 << 0)
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* Copyright (c) 2012 The Linux Foundation. All rights reserved.*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __UART_DM_H__
|
||||
#define __UART_DM_H__
|
||||
|
||||
#define PERIPH_BLK_BLSP 0
|
||||
|
||||
#define MSM_BOOT_UART_DM_EXTR_BITS(value, start_pos, end_pos) \
|
||||
((value << (32 - end_pos)) >> (32 - (end_pos - start_pos)))
|
||||
|
||||
extern void __udelay(unsigned long usec);
|
||||
|
||||
|
||||
enum MSM_BOOT_UART_DM_PARITY_MODE {
|
||||
MSM_BOOT_UART_DM_NO_PARITY,
|
||||
MSM_BOOT_UART_DM_ODD_PARITY,
|
||||
MSM_BOOT_UART_DM_EVEN_PARITY,
|
||||
MSM_BOOT_UART_DM_SPACE_PARITY
|
||||
};
|
||||
|
||||
/* UART Stop Bit Length */
|
||||
enum MSM_BOOT_UART_DM_STOP_BIT_LEN {
|
||||
MSM_BOOT_UART_DM_SBL_9_16,
|
||||
MSM_BOOT_UART_DM_SBL_1,
|
||||
MSM_BOOT_UART_DM_SBL_1_9_16,
|
||||
MSM_BOOT_UART_DM_SBL_2
|
||||
};
|
||||
|
||||
/* UART Bits per Char */
|
||||
enum MSM_BOOT_UART_DM_BITS_PER_CHAR {
|
||||
MSM_BOOT_UART_DM_5_BPS,
|
||||
MSM_BOOT_UART_DM_6_BPS,
|
||||
MSM_BOOT_UART_DM_7_BPS,
|
||||
MSM_BOOT_UART_DM_8_BPS
|
||||
};
|
||||
|
||||
/* 8-N-1 Configuration */
|
||||
#define MSM_BOOT_UART_DM_8_N_1_MODE (MSM_BOOT_UART_DM_NO_PARITY | \
|
||||
(MSM_BOOT_UART_DM_SBL_1 << 2) | \
|
||||
(MSM_BOOT_UART_DM_8_BPS << 4))
|
||||
|
||||
/* UART_DM Registers */
|
||||
|
||||
/* UART Operational Mode Register */
|
||||
#define MSM_BOOT_UART_DM_MR1(base) ((base) + 0x00)
|
||||
#define MSM_BOOT_UART_DM_MR2(base) ((base) + 0x04)
|
||||
#define MSM_BOOT_UART_DM_RXBRK_ZERO_CHAR_OFF (1 << 8)
|
||||
#define MSM_BOOT_UART_DM_LOOPBACK (1 << 7)
|
||||
|
||||
/* UART Clock Selection Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0xA0)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0x08)
|
||||
#endif
|
||||
|
||||
/* UART DM TX FIFO Registers - 4 */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x100+(4*(x)))
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x70+(4*(x)))
|
||||
#endif
|
||||
|
||||
/* UART Command Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_CR(base) ((base) + 0xA8)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_CR(base) ((base) + 0x10)
|
||||
#endif
|
||||
#define MSM_BOOT_UART_DM_CR_RX_ENABLE (1 << 0)
|
||||
#define MSM_BOOT_UART_DM_CR_RX_DISABLE (1 << 1)
|
||||
#define MSM_BOOT_UART_DM_CR_TX_ENABLE (1 << 2)
|
||||
#define MSM_BOOT_UART_DM_CR_TX_DISABLE (1 << 3)
|
||||
|
||||
/* UART Channel Command */
|
||||
#define MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) ((x & 0x0f) << 4)
|
||||
#define MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x) ((x >> 4) << 11)
|
||||
#define MSM_BOOT_UART_DM_CR_CH_CMD(x) \
|
||||
(MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) | MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x))
|
||||
#define MSM_BOOT_UART_DM_CMD_NULL MSM_BOOT_UART_DM_CR_CH_CMD(0)
|
||||
#define MSM_BOOT_UART_DM_CMD_RESET_RX MSM_BOOT_UART_DM_CR_CH_CMD(1)
|
||||
#define MSM_BOOT_UART_DM_CMD_RESET_TX MSM_BOOT_UART_DM_CR_CH_CMD(2)
|
||||
#define MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT MSM_BOOT_UART_DM_CR_CH_CMD(3)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_BRK_CHG_INT MSM_BOOT_UART_DM_CR_CH_CMD(4)
|
||||
#define MSM_BOOT_UART_DM_CMD_START_BRK MSM_BOOT_UART_DM_CR_CH_CMD(5)
|
||||
#define MSM_BOOT_UART_DM_CMD_STOP_BRK MSM_BOOT_UART_DM_CR_CH_CMD(6)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_CTS_N MSM_BOOT_UART_DM_CR_CH_CMD(7)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_STALE_INT MSM_BOOT_UART_DM_CR_CH_CMD(8)
|
||||
#define MSM_BOOT_UART_DM_CMD_PACKET_MODE MSM_BOOT_UART_DM_CR_CH_CMD(9)
|
||||
#define MSM_BOOT_UART_DM_CMD_MODE_RESET MSM_BOOT_UART_DM_CR_CH_CMD(C)
|
||||
#define MSM_BOOT_UART_DM_CMD_SET_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(D)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(E)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_TX_ERR MSM_BOOT_UART_DM_CR_CH_CMD(10)
|
||||
#define MSM_BOOT_UART_DM_CMD_CLR_TX_DONE MSM_BOOT_UART_DM_CR_CH_CMD(11)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_BRKSTRT_INT MSM_BOOT_UART_DM_CR_CH_CMD(12)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_BRKEND_INT MSM_BOOT_UART_DM_CR_CH_CMD(13)
|
||||
#define MSM_BOOT_UART_DM_CMD_RES_PER_FRM_INT MSM_BOOT_UART_DM_CR_CH_CMD(14)
|
||||
|
||||
/*UART General Command */
|
||||
#define MSM_BOOT_UART_DM_CR_GENERAL_CMD(x) ((x) << 8)
|
||||
|
||||
#define MSM_BOOT_UART_DM_GCMD_NULL MSM_BOOT_UART_DM_CR_GENERAL_CMD(0)
|
||||
#define MSM_BOOT_UART_DM_GCMD_CR_PROT_EN MSM_BOOT_UART_DM_CR_GENERAL_CMD(1)
|
||||
#define MSM_BOOT_UART_DM_GCMD_CR_PROT_DIS MSM_BOOT_UART_DM_CR_GENERAL_CMD(2)
|
||||
#define MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT MSM_BOOT_UART_DM_CR_GENERAL_CMD(3)
|
||||
#define MSM_BOOT_UART_DM_GCMD_SW_FORCE_STALE MSM_BOOT_UART_DM_CR_GENERAL_CMD(4)
|
||||
#define MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(5)
|
||||
#define MSM_BOOT_UART_DM_GCMD_DIS_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(6)
|
||||
|
||||
/* UART Interrupt Mask Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0xB0)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0x14)
|
||||
#endif
|
||||
|
||||
#define MSM_BOOT_UART_DM_TXLEV (1 << 0)
|
||||
#define MSM_BOOT_UART_DM_RXHUNT (1 << 1)
|
||||
#define MSM_BOOT_UART_DM_RXBRK_CHNG (1 << 2)
|
||||
#define MSM_BOOT_UART_DM_RXSTALE (1 << 3)
|
||||
#define MSM_BOOT_UART_DM_RXLEV (1 << 4)
|
||||
#define MSM_BOOT_UART_DM_DELTA_CTS (1 << 5)
|
||||
#define MSM_BOOT_UART_DM_CURRENT_CTS (1 << 6)
|
||||
#define MSM_BOOT_UART_DM_TX_READY (1 << 7)
|
||||
#define MSM_BOOT_UART_DM_TX_ERROR (1 << 8)
|
||||
#define MSM_BOOT_UART_DM_TX_DONE (1 << 9)
|
||||
#define MSM_BOOT_UART_DM_RXBREAK_START (1 << 10)
|
||||
#define MSM_BOOT_UART_DM_RXBREAK_END (1 << 11)
|
||||
#define MSM_BOOT_UART_DM_PAR_FRAME_ERR_IRQ (1 << 12)
|
||||
|
||||
#define MSM_BOOT_UART_DM_IMR_ENABLED (MSM_BOOT_UART_DM_TX_READY | \
|
||||
MSM_BOOT_UART_DM_TXLEV | \
|
||||
MSM_BOOT_UART_DM_RXSTALE)
|
||||
|
||||
/* UART Interrupt Programming Register */
|
||||
#define MSM_BOOT_UART_DM_IPR(base) ((base) + 0x18)
|
||||
#define MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB 0x0f
|
||||
#define MSM_BOOT_UART_DM_STALE_TIMEOUT_MSB 0 /* Not used currently */
|
||||
|
||||
/* UART Transmit/Receive FIFO Watermark Register */
|
||||
#define MSM_BOOT_UART_DM_TFWR(base) ((base) + 0x1C)
|
||||
/* Interrupt is generated when FIFO level is less than or equal to this value */
|
||||
#define MSM_BOOT_UART_DM_TFW_VALUE 0
|
||||
|
||||
#define MSM_BOOT_UART_DM_RFWR(base) ((base) + 0x20)
|
||||
/*Interrupt generated when no of words in RX FIFO is greater than this value */
|
||||
#define MSM_BOOT_UART_DM_RFW_VALUE 0
|
||||
|
||||
/* UART Hunt Character Register */
|
||||
#define MSM_BOOT_UART_DM_HCR(base) ((base) + 0x24)
|
||||
|
||||
/* Used for RX transfer initialization */
|
||||
#define MSM_BOOT_UART_DM_DMRX(base) ((base) + 0x34)
|
||||
|
||||
/* Default DMRX value - any value bigger than FIFO size would be fine */
|
||||
#define MSM_BOOT_UART_DM_DMRX_DEF_VALUE 0x220
|
||||
|
||||
/* Register to enable IRDA function */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0xB8)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0x38)
|
||||
#endif
|
||||
|
||||
/* UART Data Mover Enable Register */
|
||||
#define MSM_BOOT_UART_DM_DMEN(base) ((base) + 0x3C)
|
||||
|
||||
/* Number of characters for Transmission */
|
||||
#define MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base) ((base) + 0x040)
|
||||
|
||||
/* UART RX FIFO Base Address */
|
||||
#define MSM_BOOT_UART_DM_BADR(base) ((base) + 0x44)
|
||||
|
||||
/* UART Status Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x0A4)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x008)
|
||||
#endif
|
||||
#define MSM_BOOT_UART_DM_SR_RXRDY (1 << 0)
|
||||
#define MSM_BOOT_UART_DM_SR_RXFULL (1 << 1)
|
||||
#define MSM_BOOT_UART_DM_SR_TXRDY (1 << 2)
|
||||
#define MSM_BOOT_UART_DM_SR_TXEMT (1 << 3)
|
||||
#define MSM_BOOT_UART_DM_SR_UART_OVERRUN (1 << 4)
|
||||
#define MSM_BOOT_UART_DM_SR_PAR_FRAME_ERR (1 << 5)
|
||||
#define MSM_BOOT_UART_DM_RX_BREAK (1 << 6)
|
||||
#define MSM_BOOT_UART_DM_HUNT_CHAR (1 << 7)
|
||||
#define MSM_BOOT_UART_DM_RX_BRK_START_LAST (1 << 8)
|
||||
|
||||
/* UART Receive FIFO Registers - 4 in numbers */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x140 + (4*(x)))
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x70 + (4*(x)))
|
||||
#endif
|
||||
|
||||
/* UART Masked Interrupt Status Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0xAC)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0x10)
|
||||
#endif
|
||||
|
||||
/* UART Interrupt Status Register */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0xB4)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0x14)
|
||||
#endif
|
||||
|
||||
/* Number of characters received since the end of last RX transfer */
|
||||
#if PERIPH_BLK_BLSP
|
||||
#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0xBC)
|
||||
#else
|
||||
#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0x38)
|
||||
#endif
|
||||
|
||||
/* UART TX FIFO Status Register */
|
||||
#define MSM_BOOT_UART_DM_TXFS(base) ((base) + 0x4C)
|
||||
#define MSM_BOOT_UART_DM_TXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x, 0, 6)
|
||||
#define MSM_BOOT_UART_DM_TXFS_STATE_MSB(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 14, 31)
|
||||
#define MSM_BOOT_UART_DM_TXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x, 7, 9)
|
||||
#define MSM_BOOT_UART_DM_TXFS_ASYNC_STATE(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 10, 13)
|
||||
|
||||
/* UART RX FIFO Status Register */
|
||||
#define MSM_BOOT_UART_DM_RXFS(base) ((base) + 0x50)
|
||||
#define MSM_BOOT_UART_DM_RXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x, 0, 6)
|
||||
#define MSM_BOOT_UART_DM_RXFS_STATE_MSB(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 14, 31)
|
||||
#define MSM_BOOT_UART_DM_RXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x, 7, 9)
|
||||
#define MSM_BOOT_UART_DM_RXFS_ASYNC_STATE(x) \
|
||||
MSM_BOOT_UART_DM_EXTR_BITS(x, 10, 13)
|
||||
|
||||
/* Macros for Common Errors */
|
||||
#define MSM_BOOT_UART_DM_E_SUCCESS 0
|
||||
#define MSM_BOOT_UART_DM_E_FAILURE 1
|
||||
#define MSM_BOOT_UART_DM_E_TIMEOUT 2
|
||||
#define MSM_BOOT_UART_DM_E_INVAL 3
|
||||
#define MSM_BOOT_UART_DM_E_MALLOC_FAIL 4
|
||||
#define MSM_BOOT_UART_DM_E_RX_NOT_READY 5
|
||||
|
||||
void ipq40xx_uart_init(void);
|
||||
|
||||
#endif /* __UART_DM_H__ */
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_CLOCK_IPQ40XX_LCC_REG_H__
|
||||
#define __DRIVERS_CLOCK_IPQ40XX_LCC_REG_H__
|
||||
|
||||
#define MSM_GCC_BASE 0x00900000
|
||||
#define MSM_LPASS_LCC_BASE 0x28000000
|
||||
|
||||
/* GCC APCS Configuration/Control */
|
||||
|
||||
#define GCC_PLL_APCS_REG 0x34C0
|
||||
|
||||
#define GCC_PLL_APCS_PLL4_MASK 0x10
|
||||
#define GCC_PLL_APCS_PLL4_SHIFT 4
|
||||
#define GCC_PLL_APCS_PLL4_ENABLE (1 << GCC_PLL_APCS_PLL4_SHIFT)
|
||||
|
||||
/* LCC PLL0 Configuration/Control */
|
||||
|
||||
#define LCC_PLL0_MODE_REG 0x00
|
||||
#define LCC_PLL0_L_REG 0x04
|
||||
#define LCC_PLL0_M_REG 0x08
|
||||
#define LCC_PLL0_N_REG 0x0C
|
||||
#define LCC_PLL0_CFG_REG 0x14
|
||||
#define LCC_PLL0_STAT_REG 0x18
|
||||
|
||||
#define LCC_PLL0_MODE_FSM_RESET_MASK 0x200000
|
||||
#define LCC_PLL0_MODE_FSM_RESET_SHIFT 21
|
||||
#define LCC_PLL0_MODE_FSM_RESET_ASSERT (1 << LCC_PLL0_MODE_FSM_RESET_SHIFT)
|
||||
|
||||
#define LCC_PLL0_MODE_FSM_VOTE_MASK 0x100000
|
||||
#define LCC_PLL0_MODE_FSM_VOTE_SHIFT 20
|
||||
#define LCC_PLL0_MODE_FSM_VOTE_ENABLE (1 << LCC_PLL0_MODE_FSM_VOTE_SHIFT)
|
||||
|
||||
#define LCC_PLL0_MODE_BIAS_CNT_MASK 0xFC000
|
||||
#define LCC_PLL0_MODE_BIAS_CNT_SHIFT 14
|
||||
|
||||
#define LCC_PLL0_MODE_LOCK_CNT_MASK 0x3F00
|
||||
#define LCC_PLL0_MODE_LOCK_CNT_SHIFT 8
|
||||
|
||||
#define LCC_PLL0_MODE_XO_SEL_MASK 0x30
|
||||
#define LCC_PLL0_MODE_XO_SEL_SHIFT 4
|
||||
#define LCC_PLL0_MODE_XO_SEL_PXO (0 << LCC_PLL0_MODE_XO_SEL_SHIFT)
|
||||
#define LCC_PLL0_MODE_XO_SEL_MXO (1 << LCC_PLL0_MODE_XO_SEL_SHIFT)
|
||||
#define LCC_PLL0_MODE_XO_SEL_CXO (2 << LCC_PLL0_MODE_XO_SEL_SHIFT)
|
||||
|
||||
#define LCC_PLL0_MODE_TEST_MASK 0x8
|
||||
#define LCC_PLL0_MODE_TEST_SHIFT 3
|
||||
#define LCC_PLL0_MODE_TEST_ENABLE (1 << LCC_PLL0_MODE_TEST_SHIFT)
|
||||
|
||||
#define LCC_PLL0_MODE_RESET_MASK 0x4
|
||||
#define LCC_PLL0_MODE_RESET_SHIFT 2
|
||||
#define LCC_PLL0_MODE_RESET_DEASSERT (1 << LCC_PLL0_MODE_RESET_SHIFT)
|
||||
|
||||
#define LCC_PLL0_MODE_BYPASS_MASK 0x2
|
||||
#define LCC_PLL0_MODE_BYPASS_SHIFT 1
|
||||
#define LCC_PLL0_MODE_BYPASS_DISABLE (1 << LCC_PLL0_MODE_BYPASS_SHIFT)
|
||||
|
||||
#define LCC_PLL0_MODE_OUTPUT_MASK 0x1
|
||||
#define LCC_PLL0_MODE_OUTPUT_SHIFT 0
|
||||
#define LCC_PLL0_MODE_OUTPUT_ENABLE (1 << LCC_PLL0_MODE_OUTPUT_SHIFT)
|
||||
|
||||
#define LCC_PLL0_L_MASK 0x3FF
|
||||
#define LCC_PLL0_L_SHIFT 0
|
||||
|
||||
#define LCC_PLL0_M_MASK 0x7FFFF
|
||||
#define LCC_PLL0_M_SHIFT 0
|
||||
|
||||
#define LCC_PLL0_N_MASK 0x7FFFF
|
||||
#define LCC_PLL0_N_SHIFT 0
|
||||
|
||||
#define LCC_PLL0_CFG_LV_MAIN_MASK 0x800000
|
||||
#define LCC_PLL0_CFG_LV_MAIN_SHIFT 23
|
||||
#define LCC_PLL0_CFG_LV_MAIN_ENABLE (1 << LCC_PLL0_CFG_LV_MAIN_SHIFT)
|
||||
|
||||
#define LCC_PLL0_CFG_FRAC_MASK 0x400000
|
||||
#define LCC_PLL0_CFG_FRAC_SHIFT 22
|
||||
#define LCC_PLL0_CFG_FRAC_ENABLE (1 << LCC_PLL0_CFG_FRAC_SHIFT)
|
||||
|
||||
#define LCC_PLL0_CFG_POSTDIV_MASK 0x300000
|
||||
#define LCC_PLL0_CFG_POSTDIV_SHIFT 20
|
||||
#define LCC_PLL0_CFG_POSTDIV_DIV1 (0 << LCC_PLL0_CFG_POSTDIV_SHIFT)
|
||||
#define LCC_PLL0_CFG_POSTDIV_DIV2 (1 << LCC_PLL0_CFG_POSTDIV_SHIFT)
|
||||
#define LCC_PLL0_CFG_POSTDIV_DIV4 (2 << LCC_PLL0_CFG_POSTDIV_SHIFT)
|
||||
|
||||
#define LCC_PLL0_CFG_PREDIV_MASK 0x80000
|
||||
#define LCC_PLL0_CFG_PREDIV_SHIFT 19
|
||||
#define LCC_PLL0_CFG_PREDIV_DIV1 (0 << LCC_PLL0_CFG_PREDIV_SHIFT)
|
||||
#define LCC_PLL0_CFG_PREDIV_DIV2 (1 << LCC_PLL0_CFG_PREDIV_SHIFT)
|
||||
|
||||
#define LCC_PLL0_CFG_VCO_SEL_MASK 0x30000
|
||||
#define LCC_PLL0_CFG_VCO_SEL_SHIFT 16
|
||||
#define LCC_PLL0_CFG_VCO_SEL_LOW (0 << LCC_PLL0_CFG_VCO_SEL_SHIFT)
|
||||
#define LCC_PLL0_CFG_VCO_SEL_MED (1 << LCC_PLL0_CFG_VCO_SEL_SHIFT)
|
||||
#define LCC_PLL0_CFG_VCO_SEL_HIGH (2 << LCC_PLL0_CFG_VCO_SEL_SHIFT)
|
||||
|
||||
#define LCC_PLL0_STAT_ACTIVE_MASK 0x10000
|
||||
#define LCC_PLL0_STAT_ACTIVE_SHIFT 16
|
||||
#define LCC_PLL0_STAT_ACTIVE_SET (1 << LCC_PLL0_STAT_ACTIVE_SHIFT)
|
||||
|
||||
#define LCC_PLL0_STAT_NOCLK_MASK 0x1
|
||||
#define LCC_PLL0_STAT_NOCLK_SHIFT 0
|
||||
#define LCC_PLL0_STAT_NOCLK_SET (1 << LCC_PLL0_STAT_NOCLK_SHIFT)
|
||||
|
||||
/* LCC AHBIX Configuration/Control */
|
||||
|
||||
#define LCC_AHBIX_NS_REG 0x38
|
||||
#define LCC_AHBIX_MD_REG 0x3C
|
||||
#define LCC_AHBIX_STAT_REG 0x44
|
||||
|
||||
#define LCC_AHBIX_NS_N_VAL_MASK 0xFF000000
|
||||
#define LCC_AHBIX_NS_N_VAL_SHIFT 24
|
||||
|
||||
#define LCC_AHBIX_NS_CRC_MASK 0x800
|
||||
#define LCC_AHBIX_NS_CRC_SHIFT 11
|
||||
#define LCC_AHBIX_NS_CRC_ENABLE (1 << LCC_AHBIX_NS_CRC_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_NS_GFM_SEL_MASK 0x400
|
||||
#define LCC_AHBIX_NS_GFM_SEL_SHIFT 10
|
||||
#define LCC_AHBIX_NS_GFM_SEL_PXO (0 << LCC_AHBIX_NS_GFM_SEL_SHIFT)
|
||||
#define LCC_AHBIX_NS_GFM_SEL_MNC (1 << LCC_AHBIX_NS_GFM_SEL_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_NS_MNC_CLK_MASK 0x200
|
||||
#define LCC_AHBIX_NS_MNC_CLK_SHIFT 9
|
||||
#define LCC_AHBIX_NS_MNC_CLK_ENABLE (1 << LCC_AHBIX_NS_MNC_CLK_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_NS_MNC_MASK 0x100
|
||||
#define LCC_AHBIX_NS_MNC_SHIFT 8
|
||||
#define LCC_AHBIX_NS_MNC_ENABLE (1 << LCC_AHBIX_NS_MNC_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_NS_MNC_RESET_MASK 0x80
|
||||
#define LCC_AHBIX_NS_MNC_RESET_SHIFT 7
|
||||
#define LCC_AHBIX_NS_MNC_RESET_ASSERT (1 << LCC_AHBIX_NS_MNC_RESET_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_NS_MNC_MODE_MASK 0x60
|
||||
#define LCC_AHBIX_NS_MNC_MODE_SHIFT 5
|
||||
#define LCC_AHBIX_NS_MNC_MODE_BYPASS (0 << LCC_AHBIX_NS_MNC_MODE_SHIFT)
|
||||
#define LCC_AHBIX_NS_MNC_MODE_SWALLOW (1 << LCC_AHBIX_NS_MNC_MODE_SHIFT)
|
||||
#define LCC_AHBIX_NS_MNC_MODE_DUAL (2 << LCC_AHBIX_NS_MNC_MODE_SHIFT)
|
||||
#define LCC_AHBIX_NS_MNC_MODE_SINGLE (3 << LCC_AHBIX_NS_MNC_MODE_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_NS_PREDIV_MASK 0x18
|
||||
#define LCC_AHBIX_NS_PREDIV_SHIFT 3
|
||||
#define LCC_AHBIX_NS_PREDIV_BYPASS (0 << LCC_AHBIX_NS_PREDIV_SHIFT)
|
||||
#define LCC_AHBIX_NS_PREDIV_DIV2 (1 << LCC_AHBIX_NS_PREDIV_SHIFT)
|
||||
#define LCC_AHBIX_NS_PREDIV_DIV4 (3 << LCC_AHBIX_NS_PREDIV_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_NS_MN_SRC_MASK 0x7
|
||||
#define LCC_AHBIX_NS_MN_SRC_SHIFT 0
|
||||
#define LCC_AHBIX_NS_MN_SRC_PXO (0 << LCC_AHBIX_NS_MN_SRC_SHIFT)
|
||||
#define LCC_AHBIX_NS_MN_SRC_CXO (1 << LCC_AHBIX_NS_MN_SRC_SHIFT)
|
||||
#define LCC_AHBIX_NS_MN_SRC_LPA (2 << LCC_AHBIX_NS_MN_SRC_SHIFT)
|
||||
#define LCC_AHBIX_NS_MN_SRC_SEC (3 << LCC_AHBIX_NS_MN_SRC_SHIFT)
|
||||
#define LCC_AHBIX_NS_MN_SRC_CTEST (6 << LCC_AHBIX_NS_MN_SRC_SHIFT)
|
||||
#define LCC_AHBIX_NS_MN_SRC_PTEST (7 << LCC_AHBIX_NS_MN_SRC_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_MD_M_VAL_MASK 0xFF00
|
||||
#define LCC_AHBIX_MD_M_VAL_SHIFT 8
|
||||
|
||||
#define LCC_AHBIX_MD_NOT_2D_VAL_MASK 0xFF
|
||||
#define LCC_AHBIX_MD_NOT_2D_VAL_SHIFT 0
|
||||
|
||||
#define LCC_AHBIX_STAT_AHB_CLK_MASK 0x400
|
||||
#define LCC_AHBIX_STAT_AHB_CLK_SHIFT 10
|
||||
#define LCC_AHBIX_STAT_AHB_CLK_ON (1 << LCC_AHBIX_STAT_AHB_CLK_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_STAT_AIF_CLK_MASK 0x200
|
||||
#define LCC_AHBIX_STAT_AIF_CLK_SHIFT 9
|
||||
#define LCC_AHBIX_STAT_AIF_CLK_ON (1 << LCC_AHBIX_STAT_AIF_CLK_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_STAT_FAB2_CLK_MASK 0x40
|
||||
#define LCC_AHBIX_STAT_FAB2_CLK_SHIFT 6
|
||||
#define LCC_AHBIX_STAT_FAB2_CLK_ON (1 << LCC_AHBIX_STAT_FAB2_CLK_SHIFT)
|
||||
|
||||
#define LCC_AHBIX_STAT_2FAB_CLK_MASK 0x20
|
||||
#define LCC_AHBIX_STAT_2FAB_CLK_SHIFT 5
|
||||
#define LCC_AHBIX_STAT_2FAB_CLK_ON (1 << LCC_AHBIX_STAT_2FAB_CLK_SHIFT)
|
||||
|
||||
/* LCC MI2S Configuration/Control */
|
||||
|
||||
#define LCC_MI2S_NS_REG 0x48
|
||||
#define LCC_MI2S_MD_REG 0x4C
|
||||
#define LCC_MI2S_STAT_REG 0x50
|
||||
|
||||
#define LCC_MI2S_NS_N_VAL_MASK 0xFF000000
|
||||
#define LCC_MI2S_NS_N_VAL_SHIFT 24
|
||||
|
||||
#define LCC_MI2S_NS_RESET_MASK 0x80000
|
||||
#define LCC_MI2S_NS_RESET_SHIFT 19
|
||||
#define LCC_MI2S_NS_RESET_ASSERT (1 << LCC_MI2S_NS_RESET_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_OSR_INV_MASK 0x40000
|
||||
#define LCC_MI2S_NS_OSR_INV_SHIFT 18
|
||||
#define LCC_MI2S_NS_OSR_INV_ENABLE (1 << LCC_MI2S_NS_OSR_INV_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_OSR_CXC_MASK 0x20000
|
||||
#define LCC_MI2S_NS_OSR_CXC_SHIFT 17
|
||||
#define LCC_MI2S_NS_OSR_CXC_ENABLE (1 << LCC_MI2S_NS_OSR_CXC_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_BIT_INV_MASK 0x10000
|
||||
#define LCC_MI2S_NS_BIT_INV_SHIFT 16
|
||||
#define LCC_MI2S_NS_BIT_INV_ENABLE (1 << LCC_MI2S_NS_BIT_INV_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_BIT_CXC_MASK 0x8000
|
||||
#define LCC_MI2S_NS_BIT_CXC_SHIFT 15
|
||||
#define LCC_MI2S_NS_BIT_CXC_ENABLE (1 << LCC_MI2S_NS_BIT_CXC_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_BIT_SRC_MASK 0x4000
|
||||
#define LCC_MI2S_NS_BIT_SRC_SHIFT 14
|
||||
#define LCC_MI2S_NS_BIT_SRC_MASTER (0 << LCC_MI2S_NS_BIT_SRC_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_SRC_SLAVE (1 << LCC_MI2S_NS_BIT_SRC_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_BIT_DIV_MASK 0x3C00
|
||||
#define LCC_MI2S_NS_BIT_DIV_SHIFT 10
|
||||
#define LCC_MI2S_NS_BIT_DIV_BYPASS (0 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV2 (1 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV3 (2 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV4 (3 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV5 (4 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV6 (5 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV7 (6 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV8 (7 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV9 (8 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV10 (9 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV11 (10 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV12 (11 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV13 (12 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV14 (13 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV15 (14 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
#define LCC_MI2S_NS_BIT_DIV_DIV16 (15 << LCC_MI2S_NS_BIT_DIV_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_MNC_CLK_MASK 0x200
|
||||
#define LCC_MI2S_NS_MNC_CLK_SHIFT 9
|
||||
#define LCC_MI2S_NS_MNC_CLK_ENABLE (1 << LCC_MI2S_NS_MNC_CLK_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_MNC_MASK 0x100
|
||||
#define LCC_MI2S_NS_MNC_SHIFT 8
|
||||
#define LCC_MI2S_NS_MNC_ENABLE (1 << LCC_MI2S_NS_MNC_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_MNC_RESET_MASK 0x80
|
||||
#define LCC_MI2S_NS_MNC_RESET_SHIFT 7
|
||||
#define LCC_MI2S_NS_MNC_RESET_ASSERT (1 << LCC_MI2S_NS_MNC_RESET_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_MNC_MODE_MASK 0x60
|
||||
#define LCC_MI2S_NS_MNC_MODE_SHIFT 5
|
||||
#define LCC_MI2S_NS_MNC_MODE_BYPASS (0 << LCC_MI2S_NS_MNC_MODE_SHIFT)
|
||||
#define LCC_MI2S_NS_MNC_MODE_SWALLOW (1 << LCC_MI2S_NS_MNC_MODE_SHIFT)
|
||||
#define LCC_MI2S_NS_MNC_MODE_DUAL (2 << LCC_MI2S_NS_MNC_MODE_SHIFT)
|
||||
#define LCC_MI2S_NS_MNC_MODE_SINGLE (3 << LCC_MI2S_NS_MNC_MODE_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_PREDIV_MASK 0x18
|
||||
#define LCC_MI2S_NS_PREDIV_SHIFT 3
|
||||
#define LCC_MI2S_NS_PREDIV_BYPASS (0 << LCC_MI2S_NS_PREDIV_SHIFT)
|
||||
#define LCC_MI2S_NS_PREDIV_DIV2 (1 << LCC_MI2S_NS_PREDIV_SHIFT)
|
||||
#define LCC_MI2S_NS_PREDIV_DIV4 (3 << LCC_MI2S_NS_PREDIV_SHIFT)
|
||||
|
||||
#define LCC_MI2S_NS_MN_SRC_MASK 0x7
|
||||
#define LCC_MI2S_NS_MN_SRC_SHIFT 0
|
||||
#define LCC_MI2S_NS_MN_SRC_PXO (0 << LCC_MI2S_NS_MN_SRC_SHIFT)
|
||||
#define LCC_MI2S_NS_MN_SRC_CXO (1 << LCC_MI2S_NS_MN_SRC_SHIFT)
|
||||
#define LCC_MI2S_NS_MN_SRC_LPA (2 << LCC_MI2S_NS_MN_SRC_SHIFT)
|
||||
#define LCC_MI2S_NS_MN_SRC_SEC (3 << LCC_MI2S_NS_MN_SRC_SHIFT)
|
||||
#define LCC_MI2S_NS_MN_SRC_CTEST (6 << LCC_MI2S_NS_MN_SRC_SHIFT)
|
||||
#define LCC_MI2S_NS_MN_SRC_PTEST (7 << LCC_MI2S_NS_MN_SRC_SHIFT)
|
||||
|
||||
#define LCC_MI2S_MD_M_VAL_MASK 0xFF00
|
||||
#define LCC_MI2S_MD_M_VAL_SHIFT 8
|
||||
|
||||
#define LCC_MI2S_MD_NOT_2D_VAL_MASK 0xFF
|
||||
#define LCC_MI2S_MD_NOT_2D_VAL_SHIFT 0
|
||||
|
||||
#define LCC_MI2S_STAT_OSR_CLK_MASK 0x2
|
||||
#define LCC_MI2S_STAT_OSR_CLK_SHIFT 1
|
||||
#define LCC_MI2S_STAT_OSR_CLK_ON (1 << LCC_MI2S_STAT_OSR_CLK_SHIFT)
|
||||
|
||||
#define LCC_MI2S_STAT_BIT_CLK_MASK 0x1
|
||||
#define LCC_MI2S_STAT_BIT_CLK_SHIFT 0
|
||||
#define LCC_MI2S_STAT_BIT_CLK_ON (1 << LCC_MI2S_STAT_BIT_CLK_SHIFT)
|
||||
|
||||
/* LCC PLL Configuration/Control */
|
||||
|
||||
#define LCC_PLL_PCLK_REG 0xC4
|
||||
#define LCC_PLL_SCLK_REG 0xC8
|
||||
|
||||
#define LCC_PLL_PCLK_RESET_MASK 0x2
|
||||
#define LCC_PLL_PCLK_RESET_SHIFT 1
|
||||
#define LCC_PLL_PCLK_RESET_ASSERT (1 << LCC_PLL_PCLK_RESET_SHIFT)
|
||||
|
||||
#define LCC_PLL_PCLK_SRC_MASK 0x1
|
||||
#define LCC_PLL_PCLK_SRC_SHIFT 0
|
||||
#define LCC_PLL_PCLK_SRC_PXO (0 << LCC_PLL_PCLK_SRC_SHIFT)
|
||||
#define LCC_PLL_PCLK_SRC_PRI (1 << LCC_PLL_PCLK_SRC_SHIFT)
|
||||
|
||||
#define LCC_PLL_SCLK_RESET_MASK 0x10
|
||||
#define LCC_PLL_SCLK_RESET_SHIFT 4
|
||||
#define LCC_PLL_SCLK_RESET_ASSERT (1 << LCC_PLL_SCLK_RESET_SHIFT)
|
||||
|
||||
#define LCC_PLL_SCLK_DIV_MASK 0xC
|
||||
#define LCC_PLL_SCLK_DIV_SHIFT 2
|
||||
#define LCC_PLL_SCLK_DIV_BYPASS (0 << LCC_PLL_SCLK_DIV_SHIFT)
|
||||
#define LCC_PLL_SCLK_DIV_DIV2 (1 << LCC_PLL_SCLK_DIV_SHIFT)
|
||||
#define LCC_PLL_SCLK_DIV_DIV3 (2 << LCC_PLL_SCLK_DIV_SHIFT)
|
||||
#define LCC_PLL_SCLK_DIV_DIV4 (3 << LCC_PLL_SCLK_DIV_SHIFT)
|
||||
|
||||
#define LCC_PLL_SCLK_XO_MASK 0x2
|
||||
#define LCC_PLL_SCLK_XO_SHIFT 1
|
||||
#define LCC_PLL_SCLK_XO_PXO (0 << LCC_PLL_SCLK_XO_SHIFT)
|
||||
#define LCC_PLL_SCLK_XO_SEC (1 << LCC_PLL_SCLK_XO_SHIFT)
|
||||
|
||||
#define LCC_PLL_SCLK_MUX_MASK 0x1
|
||||
#define LCC_PLL_SCLK_MUX_SHIFT 0
|
||||
#define LCC_PLL_SCLK_MUX_PLL1 (0 << LCC_PLL_SCLK_MUX_SHIFT)
|
||||
#define LCC_PLL_SCLK_MUX_PLL0 (1 << LCC_PLL_SCLK_MUX_SHIFT)
|
||||
|
||||
#endif /* __DRIVERS_CLOCK_IPQ40XX_LCC_REG_H__ */
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* This program 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; version 2 of the License.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#include <memlayout.h>
|
||||
|
||||
#include <arch/header.ld>
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
REGION(rpm, 0x00020000, 160K, 8K)
|
||||
SRAM_START(0x2A000000)
|
||||
/* This includes bootblock image, can be reused after bootblock starts */
|
||||
/* UBER_SBL(0x2A000000, 48K) */
|
||||
/* DDR(0x2A000000, 48K) */
|
||||
BOOTBLOCK(0x2A00C000, 24K)
|
||||
OVERLAP_VERSTAGE_ROMSTAGE(0x2A012000, 64K)
|
||||
VBOOT2_WORK(0x2A022000, 16K)
|
||||
PRERAM_CBMEM_CONSOLE(0x2A026000, 32K)
|
||||
TIMESTAMP(0x2A02E000, 1K)
|
||||
|
||||
/* 0x2e400..0x3F000 67 KB free */
|
||||
|
||||
/* Keep the below area reserved at all times, it is used by various QCA
|
||||
components as shared data
|
||||
QCA_SHARED_RAM(2A03F000, 4K)
|
||||
*/
|
||||
STACK(0x2A040000, 16K)
|
||||
PRERAM_CBFS_CACHE(0x2A044000, 93K)
|
||||
TTB_SUBTABLES(0x2A05B800, 2K)
|
||||
TTB(0x2A05C000, 16K)
|
||||
SRAM_END(0x2A060000)
|
||||
|
||||
DRAM_START(0x40000000)
|
||||
RAMSTAGE(0x40640000, 128K)
|
||||
SYMBOL(memlayout_cbmem_top, 0x59F80000)
|
||||
POSTRAM_CBFS_CACHE(0x59F80000, 384K)
|
||||
DMA_COHERENT(0x5A000000, 2M)
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 - 2015 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __QUP_H__
|
||||
#define __QUP_H__
|
||||
|
||||
#include <soc/gsbi.h>
|
||||
|
||||
/* QUP block registers */
|
||||
#define QUP_CONFIG 0x0
|
||||
#define QUP_STATE 0x4
|
||||
#define QUP_IO_MODES 0x8
|
||||
#define QUP_SW_RESET 0xc
|
||||
#define QUP_TIME_OUT 0x10
|
||||
#define QUP_TIME_OUT_CURRENT 0x14
|
||||
#define QUP_OPERATIONAL 0x18
|
||||
#define QUP_ERROR_FLAGS 0x1c
|
||||
#define QUP_ERROR_FLAGS_EN 0x20
|
||||
#define QUP_TEST_CTRL 0x24
|
||||
#define QUP_MX_OUTPUT_COUNT 0x100
|
||||
#define QUP_MX_OUTPUT_CNT_CURRENT 0x104
|
||||
#define QUP_OUTPUT_DEBUG 0x108
|
||||
#define QUP_OUTPUT_FIFO_WORD_CNT 0x10c
|
||||
#define QUP_OUTPUT_FIFO 0x110
|
||||
#define QUP_MX_WRITE_COUNT 0x150
|
||||
#define QUP_WRITE_CNT_CURRENT 0x154
|
||||
#define QUP_MX_INPUT_COUNT 0x200
|
||||
#define QUP_READ_COUNT 0x208
|
||||
#define QUP_MX_READ_CNT_CURRENT 0x20c
|
||||
#define QUP_INPUT_DEBUG 0x210
|
||||
#define QUP_INPUT_FIFO_WORD_CNT 0x214
|
||||
#define QUP_INPUT_FIFO 0x218
|
||||
#define QUP_I2C_MASTER_CLK_CTL 0x400
|
||||
#define QUP_I2C_MASTER_STATUS 0x404
|
||||
|
||||
#define OUTPUT_FIFO_FULL (1<<6)
|
||||
#define INPUT_FIFO_NOT_EMPTY (1<<5)
|
||||
#define OUTPUT_FIFO_NOT_EMPTY (1<<4)
|
||||
#define INPUT_SERVICE_FLAG (1<<9)
|
||||
#define OUTPUT_SERVICE_FLAG (1<<8)
|
||||
#define QUP_OUTPUT_BIT_SHIFT_EN (1<<16)
|
||||
|
||||
#define QUP_MODE_MASK (0x03)
|
||||
#define QUP_OUTPUT_MODE_SHFT (10)
|
||||
#define QUP_INPUT_MODE_SHFT (12)
|
||||
|
||||
#define QUP_FS_DIVIDER_MASK (0xFF)
|
||||
|
||||
#define QUP_MINI_CORE_PROTO_SHFT (8)
|
||||
#define QUP_MINI_CORE_PROTO_MASK (0x0F)
|
||||
|
||||
/* Mini-core states */
|
||||
#define QUP_STATE_RESET 0x0
|
||||
#define QUP_STATE_RUN 0x1
|
||||
#define QUP_STATE_PAUSE 0x3
|
||||
#define QUP_STATE_VALID (1<<2)
|
||||
#define QUP_STATE_MASK 0x3
|
||||
#define QUP_STATE_VALID_MASK (1<<2)
|
||||
|
||||
/* Tags for output FIFO */
|
||||
#define QUP_I2C_1CLK_NOOP_SEQ 0x1 /*MSB 8-bit NOP, LSB 8-bits 1 clk.*/
|
||||
#define QUP_I2C_START_SEQ (0x1 << 8)
|
||||
#define QUP_I2C_DATA_SEQ (0x2 << 8)
|
||||
#define QUP_I2C_STOP_SEQ (0x3 << 8)
|
||||
#define QUP_I2C_RECV_SEQ (0x4 << 8)
|
||||
|
||||
/* Tags for input FIFO */
|
||||
#define QUP_I2C_MIDATA_SEQ (0x5 << 8)
|
||||
#define QUP_I2C_MISTOP_SEQ (0x6 << 8)
|
||||
#define QUP_I2C_MINACK_SEQ (0x7 << 8)
|
||||
|
||||
#define QUP_I2C_ADDR(x) ((x & 0xFF) << 1)
|
||||
#define QUP_I2C_DATA(x) (x & 0xFF)
|
||||
#define QUP_I2C_MI_TAG(x) (x & 0xFF00)
|
||||
#define QUP_I2C_SLAVE_READ (0x1)
|
||||
|
||||
/*Bit vals for I2C_MASTER_CLK_CTL register */
|
||||
#define QUP_HS_DIVIDER_SHFT (8)
|
||||
#define QUP_DIVIDER_MIN_VAL (0x3)
|
||||
|
||||
/* Bit masks for I2C_MASTER_STATUS register */
|
||||
#define QUP_I2C_INVALID_READ_SEQ (1 << 25)
|
||||
#define QUP_I2C_INVALID_READ_ADDR (1 << 24)
|
||||
#define QUP_I2C_INVALID_TAG (1 << 23)
|
||||
#define QUP_I2C_FAILED_MASK (0x3 << 6)
|
||||
#define QUP_I2C_INVALID_WRITE (1 << 5)
|
||||
#define QUP_I2C_ARB_LOST (1 << 4)
|
||||
#define QUP_I2C_PACKET_NACK (1 << 3)
|
||||
#define QUP_I2C_BUS_ERROR (1 << 2)
|
||||
|
||||
typedef enum {
|
||||
QUP_SUCCESS = 0,
|
||||
QUP_ERR_BAD_PARAM,
|
||||
QUP_ERR_STATE_SET,
|
||||
QUP_ERR_TIMEOUT,
|
||||
QUP_ERR_UNSUPPORTED,
|
||||
QUP_ERR_I2C_FAILED,
|
||||
QUP_ERR_I2C_ARB_LOST,
|
||||
QUP_ERR_I2C_BUS_ERROR,
|
||||
QUP_ERR_I2C_INVALID_SLAVE_ADDR,
|
||||
QUP_ERR_XFER_FAIL,
|
||||
QUP_ERR_I2C_NACK,
|
||||
QUP_ERR_I2C_INVALID_WRITE,
|
||||
QUP_ERR_I2C_INVALID_TAG,
|
||||
QUP_ERR_UNDEFINED,
|
||||
} qup_return_t;
|
||||
|
||||
typedef enum {
|
||||
QUP_MINICORE_SPI = 1,
|
||||
QUP_MINICORE_I2C_MASTER,
|
||||
QUP_MINICORE_I2C_SLAVE
|
||||
} qup_protocol_t;
|
||||
|
||||
typedef enum {
|
||||
QUP_MODE_FIFO = 0,
|
||||
QUP_MODE_BLOCK,
|
||||
QUP_MODE_DATAMOVER,
|
||||
} qup_mode_t;
|
||||
|
||||
typedef struct {
|
||||
qup_protocol_t protocol;
|
||||
unsigned clk_frequency;
|
||||
unsigned src_frequency;
|
||||
qup_mode_t mode;
|
||||
unsigned initialized;
|
||||
} qup_config_t;
|
||||
|
||||
typedef struct {
|
||||
qup_protocol_t protocol;
|
||||
union {
|
||||
struct {
|
||||
uint8_t addr;
|
||||
uint8_t *data;
|
||||
unsigned data_len;
|
||||
} iic;
|
||||
struct {
|
||||
void *in;
|
||||
void *out;
|
||||
unsigned size;
|
||||
} spi;
|
||||
} p;
|
||||
} qup_data_t;
|
||||
|
||||
/*
|
||||
* Initialize GSBI QUP block for FIFO I2C transfers.
|
||||
* gsbi_id[IN]: GSBI for which QUP is to be initialized.
|
||||
* config_ptr[IN]: configurations parameters for the QUP.
|
||||
*
|
||||
* return: QUP_SUCCESS, if initialization succeeds.
|
||||
*/
|
||||
qup_return_t qup_init(gsbi_id_t gsbi_id, const qup_config_t *config_ptr);
|
||||
|
||||
/*
|
||||
* Set QUP state to run, pause, reset.
|
||||
* gsbi_id[IN]: GSBI block for which QUP state is to be set.
|
||||
* state[IN]: New state to transition to.
|
||||
*
|
||||
* return: QUP_SUCCESS, if state transition succeeds.
|
||||
*/
|
||||
qup_return_t qup_set_state(gsbi_id_t gsbi_id, uint32_t state);
|
||||
|
||||
/*
|
||||
* Reset the status bits set during an i2c transfer.
|
||||
* gsbi_id[IN]: GSBI block for which i2c status bits are to be cleared.
|
||||
*
|
||||
* return: QUP_SUCCESS, if status bits are cleared successfully.
|
||||
*/
|
||||
qup_return_t qup_reset_i2c_master_status(gsbi_id_t gsbi_id);
|
||||
|
||||
/*
|
||||
* Send data to the peripheral on the bus.
|
||||
* gsbi_id[IN]: GSBI block for which data is to be sent.
|
||||
* p_tx_obj[IN]: Data to be sent to the slave on the bus.
|
||||
* stop_seq[IN]: When set to non-zero QUP engine sends i2c stop sequnce.
|
||||
*
|
||||
* return: QUP_SUCCESS, when data is sent successfully to the peripheral.
|
||||
*/
|
||||
qup_return_t qup_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
||||
uint8_t stop_seq);
|
||||
|
||||
/*
|
||||
* Receive data from peripheral on the bus.
|
||||
* gsbi_id[IN]: GSBI block from which data is to be received.
|
||||
* p_tx_obj[IN]: length of data to be received, slave address.
|
||||
* [OUT]: buffer filled with data from slave.
|
||||
*
|
||||
* return: QUP_SUCCESS, when data is received successfully.
|
||||
*/
|
||||
qup_return_t qup_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj);
|
||||
|
||||
#endif //__QUP_H__
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* This program 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; version 2 of the License.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_QUALCOMM_IPQ40XX_INCLUDE_SOC_SOC_SERVICES_H__
|
||||
#define __SOC_QUALCOMM_IPQ40XX_INCLUDE_SOC_SOC_SERVICES_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
extern u8 _memlayout_cbmem_top[];
|
||||
|
||||
/* Returns zero on success, nonzero on failure. */
|
||||
int initialize_dram(void);
|
||||
|
||||
/* Loads and runs TZBSP, switches into user mode. */
|
||||
void start_tzbsp(void);
|
||||
|
||||
/* A helper function needed to start TZBSP properly. */
|
||||
int tz_init_wrapper(int, int, void *);
|
||||
|
||||
/* Load RPM code into memory and trigger its execution. */
|
||||
void start_rpm(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* Register definitions for the IPQ GSBI Controller
|
||||
*
|
||||
* Copyright (c) 2012 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _IPQ40XX_SPI_H_
|
||||
#define _IPQ40XX_SPI_H_
|
||||
|
||||
#include <spi_flash.h>
|
||||
#include <soc/iomap.h>
|
||||
|
||||
#define QUP5_BASE ((uint32_t)GSBI_QUP5_BASE)
|
||||
#define QUP6_BASE ((uint32_t)GSBI_QUP6_BASE)
|
||||
#define QUP7_BASE ((uint32_t)GSBI_QUP7_BASE)
|
||||
|
||||
#define GSBI5_QUP5_REG_BASE (QUP5_BASE + 0x00000000)
|
||||
#define GSBI6_QUP6_REG_BASE (QUP6_BASE + 0x00000000)
|
||||
#define GSBI7_QUP7_REG_BASE (QUP7_BASE + 0x00000000)
|
||||
|
||||
#define GSBI5_REG_BASE ((uint32_t)(GSBI5_BASE + 0x00000000))
|
||||
#define GSBI6_REG_BASE ((uint32_t)(GSBI6_BASE + 0x00000000))
|
||||
#define GSBI7_REG_BASE ((uint32_t)(GSBI7_BASE + 0x00000000))
|
||||
|
||||
#define BOOT_SPI_PORT5_BASE QUP5_BASE
|
||||
#define BOOT_SPI_PORT6_BASE QUP6_BASE
|
||||
#define BOOT_SPI_PORT7_BASE QUP7_BASE
|
||||
|
||||
#define GSBI5_SPI_CONFIG_REG (GSBI5_QUP5_REG_BASE + 0x00000300)
|
||||
#define GSBI6_SPI_CONFIG_REG (GSBI6_QUP6_REG_BASE + 0x00000300)
|
||||
#define GSBI7_SPI_CONFIG_REG (GSBI7_QUP7_REG_BASE + 0x00000300)
|
||||
|
||||
#define GSBI5_SPI_IO_CONTROL_REG (GSBI5_QUP5_REG_BASE + 0x00000304)
|
||||
#define GSBI6_SPI_IO_CONTROL_REG (GSBI6_QUP6_REG_BASE + 0x00000304)
|
||||
#define GSBI7_SPI_IO_CONTROL_REG (GSBI7_QUP7_REG_BASE + 0x00000304)
|
||||
|
||||
#define GSBI5_SPI_ERROR_FLAGS_REG (GSBI5_QUP5_REG_BASE + 0x00000308)
|
||||
#define GSBI6_SPI_ERROR_FLAGS_REG (GSBI6_QUP6_REG_BASE + 0x00000308)
|
||||
#define GSBI7_SPI_ERROR_FLAGS_REG (GSBI7_QUP7_REG_BASE + 0x00000308)
|
||||
|
||||
#define GSBI5_SPI_ERROR_FLAGS_EN_REG (GSBI5_QUP5_REG_BASE + 0x0000030c)
|
||||
#define GSBI6_SPI_ERROR_FLAGS_EN_REG (GSBI6_QUP6_REG_BASE + 0x0000030c)
|
||||
#define GSBI7_SPI_ERROR_FLAGS_EN_REG (GSBI7_QUP7_REG_BASE + 0x0000030c)
|
||||
|
||||
#define GSBI5_GSBI_CTRL_REG_REG (GSBI5_REG_BASE + 0x00000000)
|
||||
#define GSBI6_GSBI_CTRL_REG_REG (GSBI6_REG_BASE + 0x00000000)
|
||||
#define GSBI7_GSBI_CTRL_REG_REG (GSBI7_REG_BASE + 0x00000000)
|
||||
|
||||
#define GSBI5_QUP_CONFIG_REG (GSBI5_QUP5_REG_BASE + 0x00000000)
|
||||
#define GSBI6_QUP_CONFIG_REG (GSBI6_QUP6_REG_BASE + 0x00000000)
|
||||
#define GSBI7_QUP_CONFIG_REG (GSBI7_QUP7_REG_BASE + 0x00000000)
|
||||
|
||||
#define GSBI5_QUP_ERROR_FLAGS_REG (GSBI5_QUP5_REG_BASE + 0x0000001c)
|
||||
#define GSBI6_QUP_ERROR_FLAGS_REG (GSBI6_QUP6_REG_BASE + 0x0000001c)
|
||||
#define GSBI7_QUP_ERROR_FLAGS_REG (GSBI7_QUP7_REG_BASE + 0x0000001c)
|
||||
|
||||
#define GSBI5_QUP_ERROR_FLAGS_EN_REG (GSBI5_QUP5_REG_BASE + 0x00000020)
|
||||
#define GSBI6_QUP_ERROR_FLAGS_EN_REG (GSBI6_QUP6_REG_BASE + 0x00000020)
|
||||
#define GSBI7_QUP_ERROR_FLAGS_EN_REG (GSBI7_QUP7_REG_BASE + 0x00000020)
|
||||
|
||||
#define GSBI5_QUP_OPERATIONAL_REG (GSBI5_QUP5_REG_BASE + 0x00000018)
|
||||
#define GSBI6_QUP_OPERATIONAL_REG (GSBI6_QUP6_REG_BASE + 0x00000018)
|
||||
#define GSBI7_QUP_OPERATIONAL_REG (GSBI7_QUP7_REG_BASE + 0x00000018)
|
||||
|
||||
#define GSBI5_QUP_IO_MODES_REG (GSBI5_QUP5_REG_BASE + 0x00000008)
|
||||
#define GSBI6_QUP_IO_MODES_REG (GSBI6_QUP6_REG_BASE + 0x00000008)
|
||||
#define GSBI7_QUP_IO_MODES_REG (GSBI7_QUP7_REG_BASE + 0x00000008)
|
||||
|
||||
#define GSBI5_QUP_STATE_REG (GSBI5_QUP5_REG_BASE + 0x00000004)
|
||||
#define GSBI6_QUP_STATE_REG (GSBI6_QUP6_REG_BASE + 0x00000004)
|
||||
#define GSBI7_QUP_STATE_REG (GSBI7_QUP7_REG_BASE + 0x00000004)
|
||||
|
||||
#define GSBI5_QUP_OUT_FIFO_WORD_CNT_REG (GSBI5_QUP5_REG_BASE + 0x0000010c)
|
||||
#define GSBI6_QUP_OUT_FIFO_WORD_CNT_REG (GSBI6_QUP6_REG_BASE + 0x0000010c)
|
||||
#define GSBI7_QUP_OUT_FIFO_WORD_CNT_REG (GSBI7_QUP7_REG_BASE + 0x0000010c)
|
||||
|
||||
#define GSBI5_QUP_IN_FIFO_WORD_CNT_REG (GSBI5_QUP5_REG_BASE + 0x00000214)
|
||||
#define GSBI6_QUP_IN_FIFO_WORD_CNT_REG (GSBI6_QUP6_REG_BASE + 0x00000214)
|
||||
#define GSBI7_QUP_IN_FIFO_WORD_CNT_REG (GSBI7_QUP7_REG_BASE + 0x00000214)
|
||||
|
||||
#define GSBI5_QUP_INPUT_FIFOc_REG(c) \
|
||||
(GSBI5_QUP5_REG_BASE + 0x00000218 + 4 * (c))
|
||||
#define GSBI6_QUP_INPUT_FIFOc_REG(c) \
|
||||
(GSBI6_QUP6_REG_BASE + 0x00000218 + 4 * (c))
|
||||
#define GSBI7_QUP_INPUT_FIFOc_REG(c) \
|
||||
(GSBI7_QUP7_REG_BASE + 0x00000218 + 4 * (c))
|
||||
|
||||
#define GSBI5_QUP_OUTPUT_FIFOc_REG(c) \
|
||||
(GSBI5_QUP5_REG_BASE + 0x00000110 + 4 * (c))
|
||||
#define GSBI6_QUP_OUTPUT_FIFOc_REG(c) \
|
||||
(GSBI6_QUP6_REG_BASE + 0x00000110 + 4 * (c))
|
||||
#define GSBI7_QUP_OUTPUT_FIFOc_REG(c) \
|
||||
(GSBI7_QUP7_REG_BASE + 0x00000110 + 4 * (c))
|
||||
|
||||
#define GSBI5_QUP_MX_INPUT_COUNT_REG (GSBI5_QUP5_REG_BASE + 0x00000200)
|
||||
#define GSBI6_QUP_MX_INPUT_COUNT_REG (GSBI6_QUP6_REG_BASE + 0x00000200)
|
||||
#define GSBI7_QUP_MX_INPUT_COUNT_REG (GSBI7_QUP7_REG_BASE + 0x00000200)
|
||||
|
||||
#define GSBI5_QUP_MX_OUTPUT_COUNT_REG (GSBI5_QUP5_REG_BASE + 0x00000100)
|
||||
#define GSBI6_QUP_MX_OUTPUT_COUNT_REG (GSBI6_QUP6_REG_BASE + 0x00000100)
|
||||
#define GSBI7_QUP_MX_OUTPUT_COUNT_REG (GSBI7_QUP7_REG_BASE + 0x00000100)
|
||||
|
||||
#define GSBI5_QUP_SW_RESET_REG (GSBI5_QUP5_REG_BASE + 0x0000000c)
|
||||
#define GSBI6_QUP_SW_RESET_REG (GSBI6_QUP6_REG_BASE + 0x0000000c)
|
||||
#define GSBI7_QUP_SW_RESET_REG (GSBI7_QUP7_REG_BASE + 0x0000000c)
|
||||
|
||||
#define CLK_CTL_REG_BASE 0x00900000
|
||||
#define GSBIn_RESET_REG(n) \
|
||||
(CLK_CTL_REG_BASE + 0x000029dc + 32 * ((n)-1))
|
||||
|
||||
#define SFAB_AHB_S3_FCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x0000216c)
|
||||
#define CFPB_CLK_NS_REG \
|
||||
(CLK_CTL_REG_BASE + 0x0000264c)
|
||||
#define SFAB_CFPB_S_HCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x000026c0)
|
||||
#define CFPB_SPLITTER_HCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x000026e0)
|
||||
#define CFPB0_HCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x00002650)
|
||||
#define CFPB2_HCLK_CTL_REG \
|
||||
(CLK_CTL_REG_BASE + 0x00002658)
|
||||
#define GSBIn_HCLK_CTL_REG(n) \
|
||||
(CLK_CTL_REG_BASE + 0x000029c0 + 32 * ((n)-1))
|
||||
#define GSBIn_QUP_APPS_NS_REG(n) \
|
||||
(CLK_CTL_REG_BASE + 0x000029cc + 32 * ((n)-1))
|
||||
#define GSBIn_QUP_APPS_MD_REG(n) \
|
||||
(CLK_CTL_REG_BASE + 0x000029c8 + 32 * ((n)-1))
|
||||
#define CLK_HALT_CFPB_STATEB_REG \
|
||||
(CLK_CTL_REG_BASE + 0x00002fd0)
|
||||
|
||||
#define GSBI5_HCLK 23
|
||||
#define GSBI6_HCLK 19
|
||||
#define GSBI7_HCLK 15
|
||||
#define GSBI5_QUP_APPS_CLK 20
|
||||
#define GSBI6_QUP_APPS_CLK 16
|
||||
#define GSBI7_QUP_APPS_CLK 12
|
||||
#define GSBI_CLK_BRANCH_ENA_MSK (1 << 4)
|
||||
#define GSBI_CLK_BRANCH_ENA (1 << 4)
|
||||
#define GSBI_CLK_BRANCH_DIS (0 << 4)
|
||||
#define QUP_CLK_BRANCH_ENA_MSK (1 << 9)
|
||||
#define QUP_CLK_BRANCH_ENA (1 << 9)
|
||||
#define QUP_CLK_BRANCH_DIS (0 << 9)
|
||||
#define CLK_ROOT_ENA_MSK (1 << 11)
|
||||
#define CLK_ROOT_ENA (1 << 11)
|
||||
#define CLK_ROOT_DIS (0 << 11)
|
||||
|
||||
#define QUP_STATE_VALID_BIT 2
|
||||
#define QUP_STATE_VALID 1
|
||||
#define QUP_STATE_MASK 0x3
|
||||
#define QUP_CONFIG_MINI_CORE_MSK (0x0F << 8)
|
||||
#define QUP_CONFIG_MINI_CORE_SPI (1 << 8)
|
||||
#define SPI_QUP_CONF_INPUT_MSK (1 << 7)
|
||||
#define SPI_QUP_CONF_INPUT_ENA (0 << 7)
|
||||
#define SPI_QUP_CONF_NO_INPUT (1 << 7)
|
||||
#define SPI_QUP_CONF_OUTPUT_MSK (1 << 6)
|
||||
#define SPI_QUP_CONF_OUTPUT_ENA (0 << 6)
|
||||
#define SPI_QUP_CONF_NO_OUTPUT (1 << 6)
|
||||
#define SPI_QUP_CONF_OUTPUT_ENA (0 << 6)
|
||||
#define QUP_STATE_RESET_STATE 0x0
|
||||
#define QUP_STATE_RUN_STATE 0x1
|
||||
#define QUP_STATE_PAUSE_STATE 0x3
|
||||
#define SPI_BIT_WORD_MSK 0x1F
|
||||
#define SPI_8_BIT_WORD 0x07
|
||||
#define PROTOCOL_CODE_MSK (0x07 << 4)
|
||||
#define PROTOCOL_CODE_SPI (0x03 << 4)
|
||||
#define LOOP_BACK_MSK (1 << 8)
|
||||
#define NO_LOOP_BACK (0 << 8)
|
||||
#define SLAVE_OPERATION_MSK (1 << 5)
|
||||
#define SLAVE_OPERATION (0 << 5)
|
||||
#define CLK_ALWAYS_ON (0 << 9)
|
||||
#define MX_CS_MODE (0 << 8)
|
||||
#define NO_TRI_STATE (1 << 0)
|
||||
#define OUTPUT_BIT_SHIFT_MSK (1 << 16)
|
||||
#define OUTPUT_BIT_SHIFT_EN (1 << 16)
|
||||
#define INPUT_BLOCK_MODE_MSK (0x03 << 12)
|
||||
#define INPUT_BLOCK_MODE (0x01 << 12)
|
||||
#define OUTPUT_BLOCK_MODE_MSK (0x03 << 10)
|
||||
#define OUTPUT_BLOCK_MODE (0x01 << 10)
|
||||
#define GSBI1_RESET (1 << 0)
|
||||
#define GSBI1_RESET_MSK 0x1
|
||||
|
||||
#define GSBI_M_VAL_SHFT 16
|
||||
#define GSBIn_M_VAL_MSK (0xFF << GSBI_M_VAL_SHFT)
|
||||
#define GSBI_N_VAL_SHFT 16
|
||||
#define GSBIn_N_VAL_MSK (0xFF << GSBI_N_VAL_SHFT)
|
||||
#define GSBI_D_VAL_SHFT 0
|
||||
#define GSBIn_D_VAL_MSK (0xFF << GSBI_D_VAL_SHFT)
|
||||
#define MNCNTR_RST_MSK (1 << 7)
|
||||
#define MNCNTR_RST_ENA (1 << 7)
|
||||
#define MNCNTR_RST_DIS (0 << 7)
|
||||
#define MNCNTR_MSK (1 << 8)
|
||||
#define MNCNTR_EN (1 << 8)
|
||||
#define MNCNTR_DIS (0 << 8)
|
||||
#define MNCNTR_MODE_MSK (0x3 << 5)
|
||||
#define MNCNTR_MODE_BYPASS (0 << 5)
|
||||
#define MNCNTR_MODE_DUAL_EDGE (0x2 << 5)
|
||||
#define GSBI_PRE_DIV_SEL_SHFT 3
|
||||
#define GSBIn_PRE_DIV_SEL_MSK (0x3 << GSBI_PRE_DIV_SEL_SHFT)
|
||||
#define GSBIn_PLL_SRC_MSK (0x03 << 0)
|
||||
#define GSBIn_PLL_SRC_PXO (0 << 0)
|
||||
#define GSBIn_PLL_SRC_PLL8 (0x3 << 0)
|
||||
|
||||
#define SPI_INPUT_FIRST_MODE (1 << 9)
|
||||
#define SPI_IO_CONTROL_CLOCK_IDLE_HIGH (1 << 10)
|
||||
#define QUP_DATA_AVAILABLE_FOR_READ (1 << 5)
|
||||
#define QUP_OUTPUT_FIFO_NOT_EMPTY (1 << 4)
|
||||
#define OUTPUT_SERVICE_FLAG (1 << 8)
|
||||
#define INPUT_SERVICE_FLAG (1 << 9)
|
||||
#define QUP_OUTPUT_FIFO_FULL (1 << 6)
|
||||
#define QUP_INPUT_FIFO_NOT_EMPTY (1 << 5)
|
||||
#define SPI_INPUT_BLOCK_SIZE 4
|
||||
#define SPI_OUTPUT_BLOCK_SIZE 4
|
||||
#define GSBI5_SPI_CLK 21
|
||||
#define GSBI5_SPI_MISO 19
|
||||
#define GSBI5_SPI_MOSI 18
|
||||
#define GSBI5_SPI_CS_0 20
|
||||
#define GSBI5_SPI_CS_1 61
|
||||
#define GSBI5_SPI_CS_2 62
|
||||
#define GSBI5_SPI_CS_3 2
|
||||
#define GSBI6_SPI_CLK 30
|
||||
#define GSBI6_SPI_CS_0 29
|
||||
#define GSBI6_SPI_MISO 28
|
||||
#define GSBI6_SPI_MOSI 27
|
||||
#define GSBI7_SPI_CLK 9
|
||||
#define GSBI7_SPI_CS_0 8
|
||||
#define GSBI7_SPI_MISO 7
|
||||
#define GSBI7_SPI_MOSI 6
|
||||
|
||||
#define MSM_GSBI_MAX_FREQ 51200000
|
||||
|
||||
#define SPI_RESET_STATE 0
|
||||
#define SPI_RUN_STATE 1
|
||||
#define SPI_PAUSE_STATE 3
|
||||
#define SPI_CORE_RESET 0
|
||||
#define SPI_CORE_RUNNING 1
|
||||
#define GSBI_SPI_MODE_0 0
|
||||
#define GSBI_SPI_MODE_1 1
|
||||
#define GSBI_SPI_MODE_2 2
|
||||
#define GSBI_SPI_MODE_3 3
|
||||
#define GSBI5_SPI 0
|
||||
#define GSBI6_SPI 1
|
||||
#define GSBI7_SPI 2
|
||||
|
||||
struct gsbi_spi {
|
||||
unsigned int spi_config;
|
||||
unsigned int io_control;
|
||||
unsigned int error_flags;
|
||||
unsigned int error_flags_en;
|
||||
unsigned int gsbi_ctrl;
|
||||
unsigned int qup_config;
|
||||
unsigned int qup_error_flags;
|
||||
unsigned int qup_error_flags_en;
|
||||
unsigned int qup_operational;
|
||||
unsigned int qup_io_modes;
|
||||
unsigned int qup_state;
|
||||
unsigned int qup_input_fifo;
|
||||
unsigned int qup_output_fifo;
|
||||
unsigned int qup_mx_input_count;
|
||||
unsigned int qup_mx_output_count;
|
||||
unsigned int qup_sw_reset;
|
||||
unsigned int qup_ns_reg;
|
||||
unsigned int qup_md_reg;
|
||||
};
|
||||
|
||||
struct ipq_spi_slave {
|
||||
struct spi_slave slave;
|
||||
const struct gsbi_spi *regs;
|
||||
unsigned int mode;
|
||||
unsigned int initialized;
|
||||
unsigned long freq;
|
||||
int allocated;
|
||||
};
|
||||
|
||||
static inline struct ipq_spi_slave *to_ipq_spi(struct spi_slave *slave)
|
||||
{
|
||||
return container_of(slave, struct ipq_spi_slave, slave);
|
||||
}
|
||||
|
||||
#endif /* _IPQ40XX_SPI_H_ */
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* This program 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; version 2 of the License.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#ifndef _IPQ40XX_USB_H_
|
||||
#define _IPQ40XX_USB_H_
|
||||
|
||||
void setup_usb_host1(void);
|
||||
void setup_usb_host2(void);
|
||||
|
||||
#endif /* _IPQ40XX_USB_H_ */
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2015 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_QUALCOMM_IPQ40XX_INCLUDE_SOC_USBL_IF_H__
|
||||
#define __SOC_QUALCOMM_IPQ40XX_INCLUDE_SOC_USBL_IF_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
typedef struct {
|
||||
u32 time_stamp;
|
||||
char msg[27];
|
||||
u8 type;
|
||||
|
||||
} boot_log_entry;
|
||||
|
||||
typedef struct {
|
||||
u32 num_log_entries;
|
||||
boot_log_entry *log;
|
||||
} sbl_ro_info;
|
||||
|
||||
typedef struct {
|
||||
u32 start_magic;
|
||||
u32 num;
|
||||
char *version;
|
||||
sbl_ro_info info[2];
|
||||
/*
|
||||
* The two addresses below can be used for communicating with the RPM
|
||||
* (passing it the starting address of the program to execute and
|
||||
* triggering the jump to the program). Presently these addresses are
|
||||
* hardcodeded in firmware source code.
|
||||
*/
|
||||
u32 *rpm_jump_trigger;
|
||||
u32 *rpm_entry_addr_ptr;
|
||||
u32 end_magic;
|
||||
} uber_sbl_shared_info;
|
||||
|
||||
#define UBER_SBL_SHARED_INFO_START_MAGIC 0x5552504d // URPM
|
||||
#define UBER_SBL_SHARED_INFO_END_MAGIC 0x554b5254 // UKRT
|
||||
|
||||
extern uber_sbl_shared_info *maskrom_param;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,316 @@
|
|||
/*
|
||||
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <delay.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/lcc-reg.h>
|
||||
#include <arch/io.h>
|
||||
|
||||
typedef struct {
|
||||
void *gcc_apcs_regs;
|
||||
void *lcc_pll0_regs;
|
||||
void *lcc_ahbix_regs;
|
||||
void *lcc_mi2s_regs;
|
||||
void *lcc_pll_regs;
|
||||
} Ipq806xLccClocks;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t apcs;
|
||||
} Ipq806xLccGccRegs;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t mode;
|
||||
uint32_t l_val;
|
||||
uint32_t m_val;
|
||||
uint32_t n_val;
|
||||
uint32_t UNUSED;
|
||||
uint32_t config;
|
||||
uint32_t status;
|
||||
} Ipq806xLccPll0Regs;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t ns;
|
||||
uint32_t md;
|
||||
uint32_t UNUSED;
|
||||
uint32_t status;
|
||||
} Ipq806xLccAhbixRegs;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t ns;
|
||||
uint32_t md;
|
||||
uint32_t status;
|
||||
} Ipq806xLccMi2sRegs;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t pri;
|
||||
uint32_t sec;
|
||||
} Ipq806xLccPllRegs;
|
||||
|
||||
struct lcc_freq_tbl {
|
||||
unsigned freq;
|
||||
unsigned pd;
|
||||
unsigned m;
|
||||
unsigned n;
|
||||
unsigned d;
|
||||
};
|
||||
|
||||
static const struct lcc_freq_tbl lcc_mi2s_freq_tbl[] = {
|
||||
{ 1024000, 4, 1, 96, 8 },
|
||||
{ 1411200, 4, 2, 139, 8 },
|
||||
{ 1536000, 4, 1, 64, 8 },
|
||||
{ 2048000, 4, 1, 48, 8 },
|
||||
{ 2116800, 4, 2, 93, 8 },
|
||||
{ 2304000, 4, 2, 85, 8 },
|
||||
{ 2822400, 4, 6, 209, 8 },
|
||||
{ 3072000, 4, 1, 32, 8 },
|
||||
{ 3175200, 4, 1, 31, 8 },
|
||||
{ 4096000, 4, 1, 24, 8 },
|
||||
{ 4233600, 4, 9, 209, 8 },
|
||||
{ 4608000, 4, 3, 64, 8 },
|
||||
{ 5644800, 4, 12, 209, 8 },
|
||||
{ 6144000, 4, 1, 16, 8 },
|
||||
{ 6350400, 4, 2, 31, 8 },
|
||||
{ 8192000, 4, 1, 12, 8 },
|
||||
{ 8467200, 4, 18, 209, 8 },
|
||||
{ 9216000, 4, 3, 32, 8 },
|
||||
{ 11289600, 4, 24, 209, 8 },
|
||||
{ 12288000, 4, 1, 8, 8 },
|
||||
{ 12700800, 4, 27, 209, 8 },
|
||||
{ 13824000, 4, 9, 64, 8 },
|
||||
{ 16384000, 4, 1, 6, 8 },
|
||||
{ 16934400, 4, 41, 238, 8 },
|
||||
{ 18432000, 4, 3, 16, 8 },
|
||||
{ 22579200, 2, 24, 209, 8 },
|
||||
{ 24576000, 4, 1, 4, 8 },
|
||||
{ 27648000, 4, 9, 32, 8 },
|
||||
{ 33868800, 4, 41, 119, 8 },
|
||||
{ 36864000, 4, 3, 8, 8 },
|
||||
{ 45158400, 1, 24, 209, 8 },
|
||||
{ 49152000, 4, 1, 2, 8 },
|
||||
{ 50803200, 1, 27, 209, 8 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int lcc_init_enable_pll0(Ipq806xLccClocks *bus)
|
||||
{
|
||||
Ipq806xLccGccRegs *gcc_regs = bus->gcc_apcs_regs;
|
||||
Ipq806xLccPll0Regs *pll0_regs = bus->lcc_pll0_regs;
|
||||
Ipq806xLccPllRegs *pll_regs = bus->lcc_pll_regs;
|
||||
uint32_t regval;
|
||||
|
||||
regval = 0;
|
||||
regval = 15 << LCC_PLL0_L_SHIFT & LCC_PLL0_L_MASK;
|
||||
write32(&pll0_regs->l_val, regval);
|
||||
|
||||
regval = 0;
|
||||
regval = 145 << LCC_PLL0_M_SHIFT & LCC_PLL0_M_MASK;
|
||||
write32(&pll0_regs->m_val, regval);
|
||||
|
||||
regval = 0;
|
||||
regval = 199 << LCC_PLL0_N_SHIFT & LCC_PLL0_N_MASK;
|
||||
write32(&pll0_regs->n_val, regval);
|
||||
|
||||
regval = 0;
|
||||
regval |= LCC_PLL0_CFG_LV_MAIN_ENABLE;
|
||||
regval |= LCC_PLL0_CFG_FRAC_ENABLE;
|
||||
write32(&pll0_regs->config, regval);
|
||||
|
||||
regval = 0;
|
||||
regval |= LCC_PLL_PCLK_SRC_PRI;
|
||||
write32(&pll_regs->pri, regval);
|
||||
|
||||
regval = 0;
|
||||
regval |= 1 << LCC_PLL0_MODE_BIAS_CNT_SHIFT &
|
||||
LCC_PLL0_MODE_BIAS_CNT_MASK;
|
||||
regval |= 8 << LCC_PLL0_MODE_LOCK_CNT_SHIFT &
|
||||
LCC_PLL0_MODE_LOCK_CNT_MASK;
|
||||
write32(&pll0_regs->mode, regval);
|
||||
|
||||
regval = read32(&gcc_regs->apcs);
|
||||
regval |= GCC_PLL_APCS_PLL4_ENABLE;
|
||||
write32(&gcc_regs->apcs, regval);
|
||||
|
||||
regval = read32(&pll0_regs->mode);
|
||||
regval |= LCC_PLL0_MODE_FSM_VOTE_ENABLE;
|
||||
write32(&pll0_regs->mode, regval);
|
||||
|
||||
mdelay(1);
|
||||
|
||||
regval = read32(&pll0_regs->status);
|
||||
if (regval & LCC_PLL0_STAT_ACTIVE_MASK)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_ERR, "%s: error enabling PLL4 clock\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lcc_init_enable_ahbix(Ipq806xLccClocks *bus)
|
||||
{
|
||||
Ipq806xLccAhbixRegs *ahbix_regs = bus->lcc_ahbix_regs;
|
||||
uint32_t regval;
|
||||
|
||||
regval = 0;
|
||||
regval |= 1 << LCC_AHBIX_MD_M_VAL_SHIFT & LCC_AHBIX_MD_M_VAL_MASK;
|
||||
regval |= 252 << LCC_AHBIX_MD_NOT_2D_VAL_SHIFT &
|
||||
LCC_AHBIX_MD_NOT_2D_VAL_MASK;
|
||||
write32(&ahbix_regs->md, regval);
|
||||
|
||||
regval = 0;
|
||||
regval |= 253 << LCC_AHBIX_NS_N_VAL_SHIFT & LCC_AHBIX_NS_N_VAL_MASK;
|
||||
regval |= LCC_AHBIX_NS_CRC_ENABLE;
|
||||
regval |= LCC_AHBIX_NS_GFM_SEL_MNC;
|
||||
regval |= LCC_AHBIX_NS_MNC_CLK_ENABLE;
|
||||
regval |= LCC_AHBIX_NS_MNC_ENABLE;
|
||||
regval |= LCC_AHBIX_NS_MNC_MODE_DUAL;
|
||||
regval |= LCC_AHBIX_NS_PREDIV_BYPASS;
|
||||
regval |= LCC_AHBIX_NS_MN_SRC_LPA;
|
||||
write32(&ahbix_regs->ns, regval);
|
||||
|
||||
mdelay(1);
|
||||
|
||||
regval = read32(&ahbix_regs->status);
|
||||
if (regval & LCC_AHBIX_STAT_AIF_CLK_MASK)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_ERR, "%s: error enabling AHBIX clock\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lcc_init_mi2s(Ipq806xLccClocks *bus, unsigned freq)
|
||||
{
|
||||
Ipq806xLccMi2sRegs *mi2s_regs = bus->lcc_mi2s_regs;
|
||||
uint32_t regval;
|
||||
uint8_t pd, m, n, d;
|
||||
unsigned i;
|
||||
|
||||
i = 0;
|
||||
while (lcc_mi2s_freq_tbl[i].freq != 0) {
|
||||
if (lcc_mi2s_freq_tbl[i].freq == freq)
|
||||
break;
|
||||
++i;
|
||||
}
|
||||
if (lcc_mi2s_freq_tbl[i].freq == 0) {
|
||||
printk(BIOS_ERR, "%s: invalid frequency given: %u\n",
|
||||
__func__, freq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (lcc_mi2s_freq_tbl[i].pd) {
|
||||
case 1:
|
||||
pd = LCC_MI2S_NS_PREDIV_BYPASS;
|
||||
break;
|
||||
case 2:
|
||||
pd = LCC_MI2S_NS_PREDIV_DIV2;
|
||||
break;
|
||||
case 4:
|
||||
pd = LCC_MI2S_NS_PREDIV_DIV4;
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_ERR, "%s: invalid prediv found: %u\n", __func__,
|
||||
lcc_mi2s_freq_tbl[i].pd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
m = lcc_mi2s_freq_tbl[i].m;
|
||||
n = ~(lcc_mi2s_freq_tbl[i].n - m);
|
||||
d = ~(lcc_mi2s_freq_tbl[i].d * 2);
|
||||
|
||||
regval = 0;
|
||||
regval |= m << LCC_MI2S_MD_M_VAL_SHIFT & LCC_MI2S_MD_M_VAL_MASK;
|
||||
regval |= d << LCC_MI2S_MD_NOT_2D_VAL_SHIFT &
|
||||
LCC_MI2S_MD_NOT_2D_VAL_MASK;
|
||||
write32(&mi2s_regs->md, regval);
|
||||
|
||||
regval = 0;
|
||||
regval |= n << LCC_MI2S_NS_N_VAL_SHIFT & LCC_MI2S_NS_N_VAL_MASK;
|
||||
regval |= LCC_MI2S_NS_BIT_DIV_DIV4;
|
||||
regval |= LCC_MI2S_NS_MNC_CLK_ENABLE;
|
||||
regval |= LCC_MI2S_NS_MNC_ENABLE;
|
||||
regval |= LCC_MI2S_NS_MNC_MODE_DUAL;
|
||||
regval |= pd;
|
||||
regval |= LCC_MI2S_NS_MN_SRC_LPA;
|
||||
write32(&mi2s_regs->ns, regval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcc_enable_mi2s(Ipq806xLccClocks *bus)
|
||||
{
|
||||
Ipq806xLccMi2sRegs *mi2s_regs = bus->lcc_mi2s_regs;
|
||||
uint32_t regval;
|
||||
|
||||
regval = read32(&mi2s_regs->ns);
|
||||
regval |= LCC_MI2S_NS_OSR_CXC_ENABLE;
|
||||
regval |= LCC_MI2S_NS_BIT_CXC_ENABLE;
|
||||
write32(&mi2s_regs->ns, regval);
|
||||
|
||||
udelay(10);
|
||||
|
||||
regval = read32(&mi2s_regs->status);
|
||||
if (regval & LCC_MI2S_STAT_OSR_CLK_MASK)
|
||||
if (regval & LCC_MI2S_STAT_BIT_CLK_MASK)
|
||||
return 0;
|
||||
|
||||
printk(BIOS_ERR, "%s: error enabling MI2S clocks: %u\n",
|
||||
__func__, regval);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int audio_clock_config(unsigned frequency)
|
||||
{
|
||||
Ipq806xLccClocks *bus = malloc(sizeof(*bus));
|
||||
|
||||
if (!bus) {
|
||||
printk(BIOS_ERR, "%s: failed to allocate bus structure\n",
|
||||
__func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bus->gcc_apcs_regs = (void *)(MSM_GCC_BASE + GCC_PLL_APCS_REG);
|
||||
bus->lcc_pll0_regs = (void *)(MSM_LPASS_LCC_BASE + LCC_PLL0_MODE_REG);
|
||||
bus->lcc_ahbix_regs = (void *)(MSM_LPASS_LCC_BASE + LCC_AHBIX_NS_REG);
|
||||
bus->lcc_mi2s_regs = (void *)(MSM_LPASS_LCC_BASE + LCC_MI2S_NS_REG);
|
||||
bus->lcc_pll_regs = (void *)(MSM_LPASS_LCC_BASE + LCC_PLL_PCLK_REG);
|
||||
|
||||
|
||||
if (lcc_init_enable_pll0(bus))
|
||||
return 1;
|
||||
if (lcc_init_enable_ahbix(bus))
|
||||
return 1;
|
||||
if (lcc_init_mi2s(bus, frequency))
|
||||
return 1;
|
||||
|
||||
if (lcc_enable_mi2s(bus))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* This program 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; version 2 of the License.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_QCA_IPQ40XX_MBN_HEADER_H__
|
||||
#define __SOC_QCA_IPQ40XX_MBN_HEADER_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
/* QCA firmware blob header gleaned from util/ipqheader/ipqheader.py */
|
||||
|
||||
struct mbn_header {
|
||||
u32 mbn_type;
|
||||
u32 mbn_version;
|
||||
u32 mbn_source;
|
||||
u32 mbn_destination;
|
||||
u32 mbn_total_size;
|
||||
u32 mbn_padding[5];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,480 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2014 - 2015 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <stdlib.h>
|
||||
#include <soc/qup.h>
|
||||
|
||||
#define TIMEOUT_CNT 100000
|
||||
|
||||
//TODO: refactor the following array to iomap driver.
|
||||
static unsigned gsbi_qup_base[] = {
|
||||
(unsigned)GSBI_QUP1_BASE,
|
||||
(unsigned)GSBI_QUP2_BASE,
|
||||
(unsigned)GSBI_QUP3_BASE,
|
||||
(unsigned)GSBI_QUP4_BASE,
|
||||
(unsigned)GSBI_QUP5_BASE,
|
||||
(unsigned)GSBI_QUP6_BASE,
|
||||
(unsigned)GSBI_QUP7_BASE,
|
||||
};
|
||||
|
||||
#define QUP_ADDR(gsbi_num, reg) ((void *)((gsbi_qup_base[gsbi_num-1]) + (reg)))
|
||||
|
||||
static qup_return_t qup_i2c_master_status(gsbi_id_t gsbi_id)
|
||||
{
|
||||
uint32_t reg_val = read32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_STATUS));
|
||||
|
||||
if (read32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS)))
|
||||
return QUP_ERR_XFER_FAIL;
|
||||
if (reg_val & QUP_I2C_INVALID_READ_ADDR)
|
||||
return QUP_ERR_I2C_INVALID_SLAVE_ADDR;
|
||||
if (reg_val & QUP_I2C_FAILED_MASK)
|
||||
return QUP_ERR_I2C_FAILED;
|
||||
if (reg_val & QUP_I2C_ARB_LOST)
|
||||
return QUP_ERR_I2C_ARB_LOST;
|
||||
if (reg_val & QUP_I2C_BUS_ERROR)
|
||||
return QUP_ERR_I2C_BUS_ERROR;
|
||||
if (reg_val & QUP_I2C_INVALID_WRITE)
|
||||
return QUP_ERR_I2C_INVALID_WRITE;
|
||||
if (reg_val & QUP_I2C_PACKET_NACK)
|
||||
return QUP_ERR_I2C_NACK;
|
||||
if (reg_val & QUP_I2C_INVALID_TAG)
|
||||
return QUP_ERR_I2C_INVALID_TAG;
|
||||
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static int check_bit_state(uint32_t *reg, int wait_for)
|
||||
{
|
||||
unsigned int count = TIMEOUT_CNT;
|
||||
|
||||
while ((read32(reg) & (QUP_STATE_VALID_MASK | QUP_STATE_MASK)) !=
|
||||
(QUP_STATE_VALID | wait_for)) {
|
||||
if (count == 0)
|
||||
return QUP_ERR_TIMEOUT;
|
||||
count--;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether GSBIn_QUP State is valid
|
||||
*/
|
||||
static qup_return_t qup_wait_for_state(gsbi_id_t gsbi_id, unsigned wait_for)
|
||||
{
|
||||
return check_bit_state(QUP_ADDR(gsbi_id, QUP_STATE), wait_for);
|
||||
}
|
||||
|
||||
qup_return_t qup_reset_i2c_master_status(gsbi_id_t gsbi_id)
|
||||
{
|
||||
/*
|
||||
* Writing a one clears the status bits.
|
||||
* Bit31-25, Bit1 and Bit0 are reserved.
|
||||
*/
|
||||
//TODO: Define each status bit. OR all status bits in a single macro.
|
||||
write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_STATUS), 0x3FFFFFC);
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_reset_master_status(gsbi_id_t gsbi_id)
|
||||
{
|
||||
write32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS), 0x7C);
|
||||
write32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS_EN), 0x7C);
|
||||
qup_reset_i2c_master_status(gsbi_id);
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_fifo_wait_for(gsbi_id_t gsbi_id, uint32_t status)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
unsigned int count = TIMEOUT_CNT;
|
||||
|
||||
while (!(read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) & status)) {
|
||||
ret = qup_i2c_master_status(gsbi_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (count == 0)
|
||||
return QUP_ERR_TIMEOUT;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_fifo_wait_while(gsbi_id_t gsbi_id, uint32_t status)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
unsigned int count = TIMEOUT_CNT;
|
||||
|
||||
while (read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) & status) {
|
||||
ret = qup_i2c_master_status(gsbi_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (count == 0)
|
||||
return QUP_ERR_TIMEOUT;
|
||||
count--;
|
||||
}
|
||||
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_write_fifo(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
||||
uint8_t stop_seq)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
uint8_t addr = p_tx_obj->p.iic.addr;
|
||||
uint8_t *data_ptr = p_tx_obj->p.iic.data;
|
||||
unsigned data_len = p_tx_obj->p.iic.data_len;
|
||||
unsigned idx = 0;
|
||||
|
||||
qup_reset_master_status(gsbi_id);
|
||||
qup_set_state(gsbi_id, QUP_STATE_RUN);
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
(QUP_I2C_START_SEQ | QUP_I2C_ADDR(addr)));
|
||||
|
||||
while (data_len) {
|
||||
if (data_len == 1 && stop_seq) {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
QUP_I2C_STOP_SEQ | QUP_I2C_DATA(data_ptr[idx]));
|
||||
} else {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
QUP_I2C_DATA_SEQ | QUP_I2C_DATA(data_ptr[idx]));
|
||||
}
|
||||
data_len--;
|
||||
idx++;
|
||||
if (data_len) {
|
||||
ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_FULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
/* Hardware sets the OUTPUT_SERVICE_FLAG flag to 1 when
|
||||
OUTPUT_FIFO_NOT_EMPTY flag in the QUP_OPERATIONAL
|
||||
register changes from 1 to 0, indicating that software
|
||||
can write more data to the output FIFO. Software should
|
||||
set OUTPUT_SERVICE_FLAG to 1 to clear it to 0, which
|
||||
means that software knows to return to fill the output
|
||||
FIFO with data.
|
||||
*/
|
||||
if (read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) &
|
||||
OUTPUT_SERVICE_FLAG) {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL),
|
||||
OUTPUT_SERVICE_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_NOT_EMPTY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
qup_set_state(gsbi_id, QUP_STATE_PAUSE);
|
||||
return qup_i2c_master_status(gsbi_id);
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_write(gsbi_id_t gsbi_id, uint8_t mode,
|
||||
qup_data_t *p_tx_obj, uint8_t stop_seq)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
||||
switch (mode) {
|
||||
case QUP_MODE_FIFO:
|
||||
ret = qup_i2c_write_fifo(gsbi_id, p_tx_obj, stop_seq);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
qup_set_state(gsbi_id, QUP_STATE_RESET);
|
||||
printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_read_fifo(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
uint8_t addr = p_tx_obj->p.iic.addr;
|
||||
uint8_t *data_ptr = p_tx_obj->p.iic.data;
|
||||
unsigned data_len = p_tx_obj->p.iic.data_len;
|
||||
unsigned idx = 0;
|
||||
|
||||
qup_reset_master_status(gsbi_id);
|
||||
qup_set_state(gsbi_id, QUP_STATE_RUN);
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
QUP_I2C_START_SEQ | (QUP_I2C_ADDR(addr) | QUP_I2C_SLAVE_READ));
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
|
||||
QUP_I2C_RECV_SEQ | data_len);
|
||||
|
||||
ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_NOT_EMPTY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL), OUTPUT_SERVICE_FLAG);
|
||||
|
||||
while (data_len) {
|
||||
uint32_t data;
|
||||
|
||||
ret = qup_fifo_wait_for(gsbi_id, INPUT_SERVICE_FLAG);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data = read32(QUP_ADDR(gsbi_id, QUP_INPUT_FIFO));
|
||||
|
||||
/*
|
||||
* Process tag and corresponding data value. For I2C master
|
||||
* mini-core, data in FIFO is composed of 16 bits and is divided
|
||||
* into an 8-bit tag for the upper bits and 8-bit data for the
|
||||
* lower bits. The 8-bit tag indicates whether the byte is the
|
||||
* last byte, or if a bus error happened during the receipt of
|
||||
* the byte.
|
||||
*/
|
||||
if ((QUP_I2C_MI_TAG(data)) == QUP_I2C_MIDATA_SEQ) {
|
||||
/* Tag: MIDATA = Master input data.*/
|
||||
data_ptr[idx] = QUP_I2C_DATA(data);
|
||||
idx++;
|
||||
data_len--;
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL),
|
||||
INPUT_SERVICE_FLAG);
|
||||
} else {
|
||||
if (QUP_I2C_MI_TAG(data) == QUP_I2C_MISTOP_SEQ) {
|
||||
/* Tag: MISTOP: Last byte of master input. */
|
||||
data_ptr[idx] = QUP_I2C_DATA(data);
|
||||
idx++;
|
||||
data_len--;
|
||||
break;
|
||||
}
|
||||
/* Tag: MINACK: Invalid master input data.*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL), INPUT_SERVICE_FLAG);
|
||||
p_tx_obj->p.iic.data_len = idx;
|
||||
qup_set_state(gsbi_id, QUP_STATE_PAUSE);
|
||||
|
||||
return QUP_SUCCESS;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_read(gsbi_id_t gsbi_id, uint8_t mode,
|
||||
qup_data_t *p_tx_obj)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
||||
switch (mode) {
|
||||
case QUP_MODE_FIFO:
|
||||
ret = qup_i2c_read_fifo(gsbi_id, p_tx_obj);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
qup_set_state(gsbi_id, QUP_STATE_RESET);
|
||||
printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
qup_return_t qup_init(gsbi_id_t gsbi_id, const qup_config_t *config_ptr)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
uint32_t reg_val;
|
||||
|
||||
/* Reset the QUP core.*/
|
||||
write32(QUP_ADDR(gsbi_id, QUP_SW_RESET), 0x1);
|
||||
|
||||
/*Wait till the reset takes effect */
|
||||
ret = qup_wait_for_state(gsbi_id, QUP_STATE_RESET);
|
||||
if (ret)
|
||||
goto bailout;
|
||||
|
||||
/* Reset the config */
|
||||
write32(QUP_ADDR(gsbi_id, QUP_CONFIG), 0);
|
||||
|
||||
/*Program the config register*/
|
||||
/*Set N value*/
|
||||
reg_val = 0x0F;
|
||||
/*Set protocol*/
|
||||
switch (config_ptr->protocol) {
|
||||
case QUP_MINICORE_I2C_MASTER:
|
||||
reg_val |= ((config_ptr->protocol &
|
||||
QUP_MINI_CORE_PROTO_MASK) <<
|
||||
QUP_MINI_CORE_PROTO_SHFT);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
goto bailout;
|
||||
}
|
||||
write32(QUP_ADDR(gsbi_id, QUP_CONFIG), reg_val);
|
||||
|
||||
/*Reset i2c clk cntl register*/
|
||||
write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_CLK_CTL), 0);
|
||||
|
||||
/*Set QUP IO Mode*/
|
||||
switch (config_ptr->mode) {
|
||||
case QUP_MODE_FIFO:
|
||||
reg_val = QUP_OUTPUT_BIT_SHIFT_EN |
|
||||
((config_ptr->mode & QUP_MODE_MASK) <<
|
||||
QUP_OUTPUT_MODE_SHFT) |
|
||||
((config_ptr->mode & QUP_MODE_MASK) <<
|
||||
QUP_INPUT_MODE_SHFT);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
goto bailout;
|
||||
}
|
||||
write32(QUP_ADDR(gsbi_id, QUP_IO_MODES), reg_val);
|
||||
|
||||
/*Set i2c clk cntl*/
|
||||
reg_val = (QUP_DIVIDER_MIN_VAL << QUP_HS_DIVIDER_SHFT);
|
||||
reg_val |= ((((config_ptr->src_frequency / config_ptr->clk_frequency)
|
||||
/ 2) - QUP_DIVIDER_MIN_VAL) &
|
||||
QUP_FS_DIVIDER_MASK);
|
||||
write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_CLK_CTL), reg_val);
|
||||
|
||||
bailout:
|
||||
if (ret)
|
||||
printk(BIOS_ERR, "failed to init qup (%d)\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
qup_return_t qup_set_state(gsbi_id_t gsbi_id, uint32_t state)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
unsigned curr_state = read32(QUP_ADDR(gsbi_id, QUP_STATE));
|
||||
|
||||
if ((state >= QUP_STATE_RESET && state <= QUP_STATE_PAUSE)
|
||||
&& (curr_state & QUP_STATE_VALID_MASK)) {
|
||||
/*
|
||||
* For PAUSE_STATE to RESET_STATE transition,
|
||||
* two writes of 10[binary]) are required for the
|
||||
* transition to complete.
|
||||
*/
|
||||
if (QUP_STATE_PAUSE == curr_state && QUP_STATE_RESET == state) {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_STATE), 0x2);
|
||||
write32(QUP_ADDR(gsbi_id, QUP_STATE), 0x2);
|
||||
} else {
|
||||
write32(QUP_ADDR(gsbi_id, QUP_STATE), state);
|
||||
}
|
||||
ret = qup_wait_for_state(gsbi_id, state);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
||||
uint8_t stop_seq)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
uint8_t mode = (read32(QUP_ADDR(gsbi_id, QUP_IO_MODES)) >>
|
||||
QUP_OUTPUT_MODE_SHFT) & QUP_MODE_MASK;
|
||||
|
||||
ret = qup_i2c_write(gsbi_id, mode, p_tx_obj, stop_seq);
|
||||
if (0) {
|
||||
int i;
|
||||
|
||||
printk(BIOS_DEBUG, "i2c tx bus %d device %2.2x:",
|
||||
gsbi_id, p_tx_obj->p.iic.addr);
|
||||
for (i = 0; i < p_tx_obj->p.iic.data_len; i++)
|
||||
printk(BIOS_DEBUG, " %2.2x", p_tx_obj->p.iic.data[i]);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
qup_return_t qup_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
|
||||
uint8_t stop_seq)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
||||
if (p_tx_obj->protocol == ((read32(QUP_ADDR(gsbi_id, QUP_CONFIG)) >>
|
||||
QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
|
||||
switch (p_tx_obj->protocol) {
|
||||
case QUP_MINICORE_I2C_MASTER:
|
||||
ret = qup_i2c_send_data(gsbi_id, p_tx_obj, stop_seq);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static qup_return_t qup_i2c_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_rx_obj)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
uint8_t mode = (read32(QUP_ADDR(gsbi_id, QUP_IO_MODES)) >>
|
||||
QUP_INPUT_MODE_SHFT) & QUP_MODE_MASK;
|
||||
|
||||
ret = qup_i2c_read(gsbi_id, mode, p_rx_obj);
|
||||
if (0) {
|
||||
int i;
|
||||
|
||||
printk(BIOS_DEBUG, "i2c rxed on bus %d device %2.2x:",
|
||||
gsbi_id, p_rx_obj->p.iic.addr);
|
||||
for (i = 0; i < p_rx_obj->p.iic.data_len; i++)
|
||||
printk(BIOS_DEBUG, " %2.2x", p_rx_obj->p.iic.data[i]);
|
||||
printk(BIOS_DEBUG, "\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
qup_return_t qup_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_rx_obj)
|
||||
{
|
||||
qup_return_t ret = QUP_ERR_UNDEFINED;
|
||||
|
||||
if (p_rx_obj->protocol == ((read32(QUP_ADDR(gsbi_id, QUP_CONFIG)) >>
|
||||
QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
|
||||
switch (p_rx_obj->protocol) {
|
||||
case QUP_MINICORE_I2C_MASTER:
|
||||
ret = qup_i2c_recv_data(gsbi_id, p_rx_obj);
|
||||
break;
|
||||
default:
|
||||
ret = QUP_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* This program 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; version 2 of the License.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <symbols.h>
|
||||
#include <soc/ipq_uart.h>
|
||||
|
||||
#define RESERVED_SIZE_KB (0x01500000 / KiB)
|
||||
|
||||
static void soc_read_resources(device_t dev)
|
||||
{
|
||||
/* Reserve bottom 0x150_0000 bytes for NSS, SMEM, etc. */
|
||||
reserved_ram_resource(dev, 0, (uintptr_t)_dram / KiB, RESERVED_SIZE_KB);
|
||||
ram_resource(dev, 0, (uintptr_t)_dram / KiB + RESERVED_SIZE_KB,
|
||||
(CONFIG_DRAM_SIZE_MB * KiB) - RESERVED_SIZE_KB);
|
||||
}
|
||||
|
||||
static void soc_init(device_t dev)
|
||||
{
|
||||
/*
|
||||
* Do this in case console is not enabled: kernel's earlyprintk()
|
||||
* should work no matter what the firmware console configuration is.
|
||||
*/
|
||||
ipq40xx_uart_init();
|
||||
|
||||
printk(BIOS_INFO, "CPU: QCA 40xx\n");
|
||||
}
|
||||
|
||||
static struct device_operations soc_ops = {
|
||||
.read_resources = soc_read_resources,
|
||||
.init = soc_init,
|
||||
};
|
||||
|
||||
static void enable_soc_dev(device_t dev)
|
||||
{
|
||||
dev->ops = &soc_ops;
|
||||
}
|
||||
|
||||
struct chip_operations soc_qualcomm_ipq40xx_ops = {
|
||||
CHIP_NAME("SOC QCA 40xx")
|
||||
.enable_dev = enable_soc_dev,
|
||||
};
|
|
@ -0,0 +1,805 @@
|
|||
/*
|
||||
* Copyright (c) 2012 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <delay.h>
|
||||
#include <gpio.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/spi.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SUCCESS 0
|
||||
|
||||
#define DUMMY_DATA_VAL 0
|
||||
#define TIMEOUT_CNT 100
|
||||
#define CS_ASSERT 1
|
||||
#define CS_DEASSERT 0
|
||||
#define NUM_PORTS 3
|
||||
#define NUM_GSBI_PINS 3
|
||||
#define TLMM_ARGS 6
|
||||
#define NUM_CS 4
|
||||
#define GSBI_PIN_IDX 0
|
||||
#define FUNC_SEL_IDX 1
|
||||
#define GPIO_DIR_IDX 2
|
||||
#define PULL_CONF_IDX 3
|
||||
#define DRV_STR_IDX 4
|
||||
#define GPIO_EN_IDX 5
|
||||
|
||||
/* Arbitrarily assigned error code values */
|
||||
#define ETIMEDOUT -10
|
||||
#define EINVAL -11
|
||||
#define EIO -12
|
||||
|
||||
#define GSBI_IDX_TO_GSBI(idx) (idx + 5)
|
||||
|
||||
|
||||
/* MX_INPUT_COUNT and MX_OUTPUT_COUNT are 16-bits. Zero has a special meaning
|
||||
* (count function disabled) and does not hold significance in the count. */
|
||||
#define MAX_PACKET_COUNT ((64 * KiB) - 1)
|
||||
|
||||
/*
|
||||
* TLMM Configuration for SPI NOR
|
||||
* gsbi_pin_conf[bus_num][GPIO_NUM, FUNC_SEL, I/O,
|
||||
* PULL UP/DOWN, DRV_STR, GPIO_FUNC]
|
||||
* gsbi_pin_conf[0][x][y] -- GSBI5
|
||||
* gsbi_pin_conf[1][x][y] -- GSBI6
|
||||
* gsbi_pin_conf[2][x][y] -- GSBI7
|
||||
*/
|
||||
static unsigned int gsbi_pin_conf[NUM_PORTS][NUM_GSBI_PINS][TLMM_ARGS] = {
|
||||
{
|
||||
/* GSBI5 CLK */
|
||||
{
|
||||
GSBI5_SPI_CLK, FUNC_SEL_1, GPIO_INPUT,
|
||||
GPIO_PULL_DOWN, GPIO_DRV_STR_11MA, GPIO_FUNC_DISABLE
|
||||
},
|
||||
/* GSBI5 MISO */
|
||||
{
|
||||
GSBI5_SPI_MISO, FUNC_SEL_1, GPIO_INPUT,
|
||||
GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
|
||||
},
|
||||
/* GSBI5 MOSI */
|
||||
{
|
||||
GSBI5_SPI_MOSI, FUNC_SEL_1, GPIO_INPUT,
|
||||
GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
|
||||
}
|
||||
},
|
||||
{
|
||||
/* GSBI6 CLK */
|
||||
{
|
||||
GSBI6_SPI_CLK, FUNC_SEL_3, GPIO_INPUT,
|
||||
GPIO_PULL_DOWN, GPIO_DRV_STR_11MA, GPIO_FUNC_DISABLE
|
||||
},
|
||||
/* GSBI6 MISO */
|
||||
{
|
||||
GSBI6_SPI_MISO, FUNC_SEL_3, GPIO_INPUT,
|
||||
GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
|
||||
},
|
||||
/* GSBI6 MOSI */
|
||||
{
|
||||
GSBI6_SPI_MOSI, FUNC_SEL_3, GPIO_INPUT,
|
||||
GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
|
||||
}
|
||||
},
|
||||
{
|
||||
/* GSBI7 CLK */
|
||||
{
|
||||
GSBI7_SPI_CLK, FUNC_SEL_1, GPIO_INPUT,
|
||||
GPIO_PULL_DOWN, GPIO_DRV_STR_11MA, GPIO_FUNC_DISABLE
|
||||
},
|
||||
/* GSBI7 MISO */
|
||||
{
|
||||
GSBI7_SPI_MISO, FUNC_SEL_1, GPIO_INPUT,
|
||||
GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
|
||||
},
|
||||
/* GSBI7 MOSI */
|
||||
{
|
||||
GSBI7_SPI_MOSI, FUNC_SEL_1, GPIO_INPUT,
|
||||
GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* CS GPIO number array cs_gpio_array[port_num][cs_num]
|
||||
* cs_gpio_array[0][x] -- GSBI5
|
||||
* cs_gpio_array[1][x] -- GSBI6
|
||||
* cs_gpio_array[2][x] -- GSBI7
|
||||
*/
|
||||
static unsigned int cs_gpio_array[NUM_PORTS][NUM_CS] = {
|
||||
{
|
||||
GSBI5_SPI_CS_0, GSBI5_SPI_CS_1, GSBI5_SPI_CS_2, GSBI5_SPI_CS_3
|
||||
},
|
||||
{
|
||||
GSBI6_SPI_CS_0, 0, 0, 0
|
||||
},
|
||||
{
|
||||
GSBI7_SPI_CS_0, 0, 0, 0
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* GSBI HCLK state register bit
|
||||
* hclk_state[0] -- GSBI5
|
||||
* hclk_state[1] -- GSBI6
|
||||
* hclk_state[2] -- GSBI7
|
||||
*/
|
||||
static unsigned int hclk_state[NUM_PORTS] = {
|
||||
GSBI5_HCLK,
|
||||
GSBI6_HCLK,
|
||||
GSBI7_HCLK
|
||||
};
|
||||
|
||||
/*
|
||||
* GSBI QUP_APPS_CLK state register bit
|
||||
* qup_apps_clk_state[0] -- GSBI5
|
||||
* qup_apps_clk_state[1] -- GSBI6
|
||||
* qup_apps_clk_state[2] -- GSBI7
|
||||
*/
|
||||
static unsigned int qup_apps_clk_state[NUM_PORTS] = {
|
||||
GSBI5_QUP_APPS_CLK,
|
||||
GSBI6_QUP_APPS_CLK,
|
||||
GSBI7_QUP_APPS_CLK
|
||||
};
|
||||
|
||||
|
||||
static int check_bit_state(uint32_t reg_addr, int bit_num,
|
||||
int val, int us_delay)
|
||||
{
|
||||
unsigned int count = TIMEOUT_CNT;
|
||||
unsigned int bit_val = ((readl_i(reg_addr) >> bit_num) & 0x01);
|
||||
|
||||
while (bit_val != val) {
|
||||
count--;
|
||||
if (count == 0)
|
||||
return -ETIMEDOUT;
|
||||
udelay(us_delay);
|
||||
bit_val = ((readl_i(reg_addr) >> bit_num) & 0x01);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether GSBIn_QUP State is valid
|
||||
*/
|
||||
static int check_qup_state_valid(struct ipq_spi_slave *ds)
|
||||
{
|
||||
|
||||
return check_bit_state(ds->regs->qup_state, QUP_STATE_VALID_BIT,
|
||||
QUP_STATE_VALID, 1);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure GSBIn Core state
|
||||
*/
|
||||
static int config_spi_state(struct ipq_spi_slave *ds, unsigned int state)
|
||||
{
|
||||
uint32_t val;
|
||||
int ret;
|
||||
uint32_t new_state;
|
||||
|
||||
ret = check_qup_state_valid(ds);
|
||||
if (ret != SUCCESS)
|
||||
return ret;
|
||||
|
||||
switch (state) {
|
||||
case SPI_RUN_STATE:
|
||||
new_state = QUP_STATE_RUN_STATE;
|
||||
break;
|
||||
|
||||
case SPI_RESET_STATE:
|
||||
new_state = QUP_STATE_RESET_STATE;
|
||||
break;
|
||||
|
||||
case SPI_PAUSE_STATE:
|
||||
new_state = QUP_STATE_PAUSE_STATE;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(BIOS_ERR,
|
||||
"err: unsupported GSBI SPI state : %d\n", state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set the state as requested */
|
||||
val = (readl_i(ds->regs->qup_state) & ~QUP_STATE_MASK)
|
||||
| new_state;
|
||||
writel_i(val, ds->regs->qup_state);
|
||||
return check_qup_state_valid(ds);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set GSBIn SPI Mode
|
||||
*/
|
||||
static void spi_set_mode(struct ipq_spi_slave *ds, unsigned int mode)
|
||||
{
|
||||
unsigned int clk_idle_state;
|
||||
unsigned int input_first_mode;
|
||||
uint32_t val;
|
||||
|
||||
switch (mode) {
|
||||
case GSBI_SPI_MODE_0:
|
||||
clk_idle_state = 0;
|
||||
input_first_mode = SPI_INPUT_FIRST_MODE;
|
||||
break;
|
||||
case GSBI_SPI_MODE_1:
|
||||
clk_idle_state = 0;
|
||||
input_first_mode = 0;
|
||||
break;
|
||||
case GSBI_SPI_MODE_2:
|
||||
clk_idle_state = 1;
|
||||
input_first_mode = SPI_INPUT_FIRST_MODE;
|
||||
break;
|
||||
case GSBI_SPI_MODE_3:
|
||||
clk_idle_state = 1;
|
||||
input_first_mode = 0;
|
||||
break;
|
||||
default:
|
||||
printk(BIOS_ERR,
|
||||
"err : unsupported spi mode : %d\n", mode);
|
||||
return;
|
||||
}
|
||||
|
||||
val = readl_i(ds->regs->spi_config);
|
||||
val |= input_first_mode;
|
||||
writel_i(val, ds->regs->spi_config);
|
||||
|
||||
val = readl_i(ds->regs->io_control);
|
||||
if (clk_idle_state)
|
||||
val |= SPI_IO_CONTROL_CLOCK_IDLE_HIGH;
|
||||
else
|
||||
val &= ~SPI_IO_CONTROL_CLOCK_IDLE_HIGH;
|
||||
|
||||
writel_i(val, ds->regs->io_control);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for HCLK state
|
||||
*/
|
||||
static int check_hclk_state(unsigned int core_num, int enable)
|
||||
{
|
||||
return check_bit_state(CLK_HALT_CFPB_STATEB_REG,
|
||||
hclk_state[core_num], enable, 5);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for QUP APPS CLK state
|
||||
*/
|
||||
static int check_qup_clk_state(unsigned int core_num, int enable)
|
||||
{
|
||||
return check_bit_state(CLK_HALT_CFPB_STATEB_REG,
|
||||
qup_apps_clk_state[core_num], enable, 5);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to assert and De-assert chip select
|
||||
*/
|
||||
static void CS_change(int port_num, int cs_num, int enable)
|
||||
{
|
||||
unsigned int cs_gpio = cs_gpio_array[port_num][cs_num];
|
||||
void *addr = GPIO_IN_OUT_ADDR(cs_gpio);
|
||||
uint32_t val = readl_i(addr);
|
||||
|
||||
val &= (~(1 << GPIO_OUTPUT));
|
||||
if (!enable)
|
||||
val |= (1 << GPIO_OUTPUT);
|
||||
write32(addr, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* GSBIn TLMM configuration
|
||||
*/
|
||||
static void gsbi_pin_config(unsigned int port_num, int cs_num)
|
||||
{
|
||||
unsigned int gpio;
|
||||
unsigned int i;
|
||||
/* Hold the GSBIn (core_num) core in reset */
|
||||
clrsetbits_le32_i(GSBIn_RESET_REG(GSBI_IDX_TO_GSBI(port_num)),
|
||||
GSBI1_RESET_MSK, GSBI1_RESET);
|
||||
|
||||
/*
|
||||
* Configure SPI_CLK, SPI_MISO and SPI_MOSI
|
||||
*/
|
||||
for (i = 0; i < NUM_GSBI_PINS; i++) {
|
||||
unsigned int func_sel;
|
||||
unsigned int io_config;
|
||||
unsigned int pull_config;
|
||||
unsigned int drv_strength;
|
||||
unsigned int gpio_en;
|
||||
unsigned int *ptr;
|
||||
|
||||
ptr = gsbi_pin_conf[port_num][i];
|
||||
gpio = *(ptr + GSBI_PIN_IDX);
|
||||
func_sel = *(ptr + FUNC_SEL_IDX);
|
||||
io_config = *(ptr + GPIO_DIR_IDX);
|
||||
pull_config = *(ptr + PULL_CONF_IDX);
|
||||
drv_strength = *(ptr + DRV_STR_IDX);
|
||||
gpio_en = *(ptr + GPIO_EN_IDX);
|
||||
|
||||
gpio_tlmm_config(gpio, func_sel, io_config,
|
||||
pull_config, drv_strength, gpio_en);
|
||||
}
|
||||
|
||||
gpio = cs_gpio_array[port_num][cs_num];
|
||||
/* configure CS */
|
||||
gpio_tlmm_config(gpio, FUNC_SEL_GPIO, GPIO_OUTPUT, GPIO_PULL_UP,
|
||||
GPIO_DRV_STR_10MA, GPIO_FUNC_ENABLE);
|
||||
CS_change(port_num, cs_num, CS_DEASSERT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clock configuration for GSBIn Core
|
||||
*/
|
||||
static int gsbi_clock_init(struct ipq_spi_slave *ds)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Hold the GSBIn (core_num) core in reset */
|
||||
clrsetbits_le32_i(GSBIn_RESET_REG(GSBI_IDX_TO_GSBI(ds->slave.bus)),
|
||||
GSBI1_RESET_MSK, GSBI1_RESET);
|
||||
|
||||
/* Disable GSBIn (core_num) QUP core clock branch */
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, QUP_CLK_BRANCH_ENA_MSK,
|
||||
QUP_CLK_BRANCH_DIS);
|
||||
|
||||
ret = check_qup_clk_state(ds->slave.bus, 1);
|
||||
if (ret) {
|
||||
printk(BIOS_ERR,
|
||||
"QUP Clock Halt For GSBI%d failed!\n", ds->slave.bus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable M/N:D counter and hold M/N:D counter in reset */
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, (MNCNTR_MSK | MNCNTR_RST_MSK),
|
||||
(MNCNTR_RST_ENA | MNCNTR_DIS));
|
||||
|
||||
/* Disable GSBIn (core_num) QUP core clock root */
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, CLK_ROOT_ENA_MSK, CLK_ROOT_DIS);
|
||||
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, GSBIn_PLL_SRC_MSK,
|
||||
GSBIn_PLL_SRC_PLL8);
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, GSBIn_PRE_DIV_SEL_MSK,
|
||||
(0 << GSBI_PRE_DIV_SEL_SHFT));
|
||||
|
||||
/* Program M/N:D values for GSBIn_QUP_APPS_CLK @50MHz */
|
||||
clrsetbits_le32_i(ds->regs->qup_md_reg, GSBIn_M_VAL_MSK,
|
||||
(0x01 << GSBI_M_VAL_SHFT));
|
||||
clrsetbits_le32_i(ds->regs->qup_md_reg, GSBIn_D_VAL_MSK,
|
||||
(0xF7 << GSBI_D_VAL_SHFT));
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, GSBIn_N_VAL_MSK,
|
||||
(0xF8 << GSBI_N_VAL_SHFT));
|
||||
|
||||
/* Set MNCNTR_MODE = 0: Bypass mode */
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, MNCNTR_MODE_MSK,
|
||||
MNCNTR_MODE_DUAL_EDGE);
|
||||
|
||||
/* De-assert the M/N:D counter reset */
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, MNCNTR_RST_MSK, MNCNTR_RST_DIS);
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, MNCNTR_MSK, MNCNTR_EN);
|
||||
|
||||
/*
|
||||
* Enable the GSBIn (core_num) QUP core clock root.
|
||||
* Keep MND counter disabled
|
||||
*/
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, CLK_ROOT_ENA_MSK, CLK_ROOT_ENA);
|
||||
|
||||
/* Enable GSBIn (core_num) QUP core clock branch */
|
||||
clrsetbits_le32_i(ds->regs->qup_ns_reg, QUP_CLK_BRANCH_ENA_MSK,
|
||||
QUP_CLK_BRANCH_ENA);
|
||||
|
||||
ret = check_qup_clk_state(ds->slave.bus, 0);
|
||||
if (ret) {
|
||||
printk(BIOS_ERR,
|
||||
"QUP Clock Enable For GSBI%d failed!\n", ds->slave.bus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable GSBIn (core_num) core clock branch */
|
||||
clrsetbits_le32_i(GSBIn_HCLK_CTL_REG(GSBI_IDX_TO_GSBI(ds->slave.bus)),
|
||||
GSBI_CLK_BRANCH_ENA_MSK, GSBI_CLK_BRANCH_ENA);
|
||||
|
||||
ret = check_hclk_state(ds->slave.bus, 0);
|
||||
if (ret) {
|
||||
printk(BIOS_ERR,
|
||||
"HCLK Enable For GSBI%d failed!\n", ds->slave.bus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Release GSBIn (core_num) core from reset */
|
||||
clrsetbits_le32_i(GSBIn_RESET_REG(GSBI_IDX_TO_GSBI(ds->slave.bus)),
|
||||
GSBI1_RESET_MSK, 0);
|
||||
udelay(50);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset entire QUP and all mini cores
|
||||
*/
|
||||
static void spi_reset(struct ipq_spi_slave *ds)
|
||||
{
|
||||
writel_i(0x1, ds->regs->qup_sw_reset);
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
static const struct gsbi_spi spi_reg[] = {
|
||||
/* GSBI5 registers for SPI interface */
|
||||
{
|
||||
GSBI5_SPI_CONFIG_REG,
|
||||
GSBI5_SPI_IO_CONTROL_REG,
|
||||
GSBI5_SPI_ERROR_FLAGS_REG,
|
||||
GSBI5_SPI_ERROR_FLAGS_EN_REG,
|
||||
GSBI5_GSBI_CTRL_REG_REG,
|
||||
GSBI5_QUP_CONFIG_REG,
|
||||
GSBI5_QUP_ERROR_FLAGS_REG,
|
||||
GSBI5_QUP_ERROR_FLAGS_EN_REG,
|
||||
GSBI5_QUP_OPERATIONAL_REG,
|
||||
GSBI5_QUP_IO_MODES_REG,
|
||||
GSBI5_QUP_STATE_REG,
|
||||
GSBI5_QUP_INPUT_FIFOc_REG(0),
|
||||
GSBI5_QUP_OUTPUT_FIFOc_REG(0),
|
||||
GSBI5_QUP_MX_INPUT_COUNT_REG,
|
||||
GSBI5_QUP_MX_OUTPUT_COUNT_REG,
|
||||
GSBI5_QUP_SW_RESET_REG,
|
||||
GSBIn_QUP_APPS_NS_REG(5),
|
||||
GSBIn_QUP_APPS_MD_REG(5),
|
||||
},
|
||||
/* GSBI6 registers for SPI interface */
|
||||
{
|
||||
GSBI6_SPI_CONFIG_REG,
|
||||
GSBI6_SPI_IO_CONTROL_REG,
|
||||
GSBI6_SPI_ERROR_FLAGS_REG,
|
||||
GSBI6_SPI_ERROR_FLAGS_EN_REG,
|
||||
GSBI6_GSBI_CTRL_REG_REG,
|
||||
GSBI6_QUP_CONFIG_REG,
|
||||
GSBI6_QUP_ERROR_FLAGS_REG,
|
||||
GSBI6_QUP_ERROR_FLAGS_EN_REG,
|
||||
GSBI6_QUP_OPERATIONAL_REG,
|
||||
GSBI6_QUP_IO_MODES_REG,
|
||||
GSBI6_QUP_STATE_REG,
|
||||
GSBI6_QUP_INPUT_FIFOc_REG(0),
|
||||
GSBI6_QUP_OUTPUT_FIFOc_REG(0),
|
||||
GSBI6_QUP_MX_INPUT_COUNT_REG,
|
||||
GSBI6_QUP_MX_OUTPUT_COUNT_REG,
|
||||
GSBI6_QUP_SW_RESET_REG,
|
||||
GSBIn_QUP_APPS_NS_REG(6),
|
||||
GSBIn_QUP_APPS_MD_REG(6),
|
||||
},
|
||||
/* GSBI7 registers for SPI interface */
|
||||
{
|
||||
GSBI7_SPI_CONFIG_REG,
|
||||
GSBI7_SPI_IO_CONTROL_REG,
|
||||
GSBI7_SPI_ERROR_FLAGS_REG,
|
||||
GSBI7_SPI_ERROR_FLAGS_EN_REG,
|
||||
GSBI7_GSBI_CTRL_REG_REG,
|
||||
GSBI7_QUP_CONFIG_REG,
|
||||
GSBI7_QUP_ERROR_FLAGS_REG,
|
||||
GSBI7_QUP_ERROR_FLAGS_EN_REG,
|
||||
GSBI7_QUP_OPERATIONAL_REG,
|
||||
GSBI7_QUP_IO_MODES_REG,
|
||||
GSBI7_QUP_STATE_REG,
|
||||
GSBI7_QUP_INPUT_FIFOc_REG(0),
|
||||
GSBI7_QUP_OUTPUT_FIFOc_REG(0),
|
||||
GSBI7_QUP_MX_INPUT_COUNT_REG,
|
||||
GSBI7_QUP_MX_OUTPUT_COUNT_REG,
|
||||
GSBI7_QUP_SW_RESET_REG,
|
||||
GSBIn_QUP_APPS_NS_REG(7),
|
||||
GSBIn_QUP_APPS_MD_REG(7),
|
||||
}
|
||||
};
|
||||
static struct ipq_spi_slave spi_slave_pool[2];
|
||||
|
||||
void spi_init(void)
|
||||
{
|
||||
/* just in case */
|
||||
memset(spi_slave_pool, 0, sizeof(spi_slave_pool));
|
||||
}
|
||||
|
||||
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs)
|
||||
{
|
||||
struct ipq_spi_slave *ds = NULL;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* IPQ GSBI (Generic Serial Bus Interface) supports SPI Flash
|
||||
* on different GSBI5, GSBI6 and GSBI7
|
||||
* with different number of chip selects (CS, channels):
|
||||
*/
|
||||
if ((bus < GSBI5_SPI) || (bus > GSBI7_SPI)
|
||||
|| ((bus == GSBI5_SPI) && (cs > 3))
|
||||
|| ((bus == GSBI6_SPI) && (cs > 0))
|
||||
|| ((bus == GSBI7_SPI) && (cs > 0))) {
|
||||
printk(BIOS_ERR, "SPI error: unsupported bus %d (Supported busses 0,1 and 2) or chipselect\n",
|
||||
bus);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) {
|
||||
if (spi_slave_pool[i].allocated)
|
||||
continue;
|
||||
ds = spi_slave_pool + i;
|
||||
ds->slave.bus = bus;
|
||||
ds->slave.cs = cs;
|
||||
ds->regs = &spi_reg[bus];
|
||||
|
||||
/*
|
||||
* TODO(vbendeb):
|
||||
* hardcoded frequency and mode - we might need to find a way
|
||||
* to configure this
|
||||
*/
|
||||
ds->freq = 10000000;
|
||||
ds->mode = GSBI_SPI_MODE_0;
|
||||
ds->allocated = 1;
|
||||
|
||||
return &ds->slave;
|
||||
}
|
||||
|
||||
printk(BIOS_ERR, "SPI error: all %d pools busy\n", i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* GSBIn SPI Hardware Initialisation
|
||||
*/
|
||||
static int spi_hw_init(struct ipq_spi_slave *ds)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ds->initialized)
|
||||
return 0;
|
||||
|
||||
/* GSBI module configuration */
|
||||
spi_reset(ds);
|
||||
|
||||
/* Set the GSBIn QUP state */
|
||||
ret = config_spi_state(ds, SPI_RESET_STATE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Configure GSBI_CTRL register to set protocol_mode to SPI:011 */
|
||||
clrsetbits_le32_i(ds->regs->gsbi_ctrl, PROTOCOL_CODE_MSK,
|
||||
PROTOCOL_CODE_SPI);
|
||||
|
||||
/*
|
||||
* Configure Mini core to SPI core with Input Output enabled,
|
||||
* SPI master, N = 8 bits
|
||||
*/
|
||||
clrsetbits_le32_i(ds->regs->qup_config, (QUP_CONFIG_MINI_CORE_MSK |
|
||||
SPI_QUP_CONF_INPUT_MSK |
|
||||
SPI_QUP_CONF_OUTPUT_MSK |
|
||||
SPI_BIT_WORD_MSK),
|
||||
(QUP_CONFIG_MINI_CORE_SPI |
|
||||
SPI_QUP_CONF_NO_INPUT |
|
||||
SPI_QUP_CONF_NO_OUTPUT |
|
||||
SPI_8_BIT_WORD));
|
||||
|
||||
/*
|
||||
* Configure Input first SPI protocol,
|
||||
* SPI master mode and no loopback
|
||||
*/
|
||||
clrsetbits_le32_i(ds->regs->spi_config, (LOOP_BACK_MSK |
|
||||
SLAVE_OPERATION_MSK),
|
||||
(NO_LOOP_BACK |
|
||||
SLAVE_OPERATION));
|
||||
|
||||
/*
|
||||
* Configure SPI IO Control Register
|
||||
* CLK_ALWAYS_ON = 0
|
||||
* MX_CS_MODE = 0
|
||||
* NO_TRI_STATE = 1
|
||||
*/
|
||||
writel_i((CLK_ALWAYS_ON | MX_CS_MODE | NO_TRI_STATE),
|
||||
ds->regs->io_control);
|
||||
|
||||
/*
|
||||
* Configure SPI IO Modes.
|
||||
* OUTPUT_BIT_SHIFT_EN = 1
|
||||
* INPUT_MODE = Block Mode
|
||||
* OUTPUT MODE = Block Mode
|
||||
*/
|
||||
clrsetbits_le32_i(ds->regs->qup_io_modes, (OUTPUT_BIT_SHIFT_MSK |
|
||||
INPUT_BLOCK_MODE_MSK |
|
||||
OUTPUT_BLOCK_MODE_MSK),
|
||||
(OUTPUT_BIT_SHIFT_EN |
|
||||
INPUT_BLOCK_MODE |
|
||||
OUTPUT_BLOCK_MODE));
|
||||
|
||||
spi_set_mode(ds, ds->mode);
|
||||
|
||||
/* Disable Error mask */
|
||||
writel_i(0, ds->regs->error_flags_en);
|
||||
writel_i(0, ds->regs->qup_error_flags_en);
|
||||
|
||||
ds->initialized = 1;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int spi_claim_bus(struct spi_slave *slave)
|
||||
{
|
||||
struct ipq_spi_slave *ds = to_ipq_spi(slave);
|
||||
unsigned int ret;
|
||||
|
||||
if (ds->initialized)
|
||||
return SUCCESS;
|
||||
|
||||
/* GPIO Configuration for SPI port */
|
||||
gsbi_pin_config(ds->slave.bus, ds->slave.cs);
|
||||
|
||||
/* Clock configuration */
|
||||
ret = gsbi_clock_init(ds);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = spi_hw_init(ds);
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void spi_release_bus(struct spi_slave *slave)
|
||||
{
|
||||
struct ipq_spi_slave *ds = to_ipq_spi(slave);
|
||||
|
||||
/* Reset the SPI hardware */
|
||||
spi_reset(ds);
|
||||
ds->initialized = 0;
|
||||
}
|
||||
|
||||
static int spi_xfer_tx_packet(struct ipq_spi_slave *ds,
|
||||
const uint8_t *dout, unsigned out_bytes)
|
||||
{
|
||||
int ret;
|
||||
|
||||
writel_i(out_bytes, ds->regs->qup_mx_output_count);
|
||||
|
||||
ret = config_spi_state(ds, SPI_RUN_STATE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
while (out_bytes) {
|
||||
if (readl_i(ds->regs->qup_operational) & QUP_OUTPUT_FIFO_FULL)
|
||||
continue;
|
||||
|
||||
writel_i(*dout++, ds->regs->qup_output_fifo);
|
||||
out_bytes--;
|
||||
|
||||
/* Wait for output FIFO to drain. */
|
||||
if (!out_bytes)
|
||||
while (readl_i(ds->regs->qup_operational) &
|
||||
QUP_OUTPUT_FIFO_NOT_EMPTY)
|
||||
;
|
||||
}
|
||||
|
||||
return config_spi_state(ds, SPI_RESET_STATE);
|
||||
}
|
||||
|
||||
static int spi_xfer_rx_packet(struct ipq_spi_slave *ds,
|
||||
uint8_t *din, unsigned in_bytes)
|
||||
{
|
||||
int ret;
|
||||
|
||||
writel_i(in_bytes, ds->regs->qup_mx_input_count);
|
||||
writel_i(in_bytes, ds->regs->qup_mx_output_count);
|
||||
|
||||
ret = config_spi_state(ds, SPI_RUN_STATE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Seed clocking */
|
||||
writel_i(0xff, ds->regs->qup_output_fifo);
|
||||
while (in_bytes) {
|
||||
if (!(readl_i(ds->regs->qup_operational) &
|
||||
QUP_INPUT_FIFO_NOT_EMPTY))
|
||||
continue;
|
||||
/* Keep it clocking */
|
||||
writel_i(0xff, ds->regs->qup_output_fifo);
|
||||
|
||||
*din++ = readl_i(ds->regs->qup_input_fifo) & 0xff;
|
||||
in_bytes--;
|
||||
}
|
||||
|
||||
return config_spi_state(ds, SPI_RESET_STATE);
|
||||
}
|
||||
|
||||
unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
|
||||
{
|
||||
return min(MAX_PACKET_COUNT, buf_len);
|
||||
}
|
||||
|
||||
int spi_xfer(struct spi_slave *slave, const void *dout,
|
||||
unsigned out_bytes, void *din, unsigned in_bytes)
|
||||
{
|
||||
int ret;
|
||||
struct ipq_spi_slave *ds = to_ipq_spi(slave);
|
||||
|
||||
/* Assert the chip select */
|
||||
CS_change(ds->slave.bus, ds->slave.cs, CS_ASSERT);
|
||||
|
||||
ret = config_spi_state(ds, SPI_RESET_STATE);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (!out_bytes)
|
||||
goto spi_receive;
|
||||
|
||||
/*
|
||||
* Let's do the write side of the transaction first. Enable output
|
||||
* FIFO.
|
||||
*/
|
||||
clrsetbits_le32_i(ds->regs->qup_config, SPI_QUP_CONF_OUTPUT_MSK,
|
||||
SPI_QUP_CONF_OUTPUT_ENA);
|
||||
|
||||
while (out_bytes) {
|
||||
unsigned todo = MIN(out_bytes, MAX_PACKET_COUNT);
|
||||
|
||||
ret = spi_xfer_tx_packet(ds, dout, todo);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
out_bytes -= todo;
|
||||
dout += todo;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
spi_receive:
|
||||
if (!in_bytes) /* Nothing to read. */
|
||||
goto out;
|
||||
|
||||
/* Enable input FIFO */
|
||||
clrsetbits_le32_i(ds->regs->qup_config, SPI_QUP_CONF_INPUT_MSK,
|
||||
SPI_QUP_CONF_INPUT_ENA);
|
||||
|
||||
while (in_bytes) {
|
||||
unsigned todo = MIN(in_bytes, MAX_PACKET_COUNT);
|
||||
|
||||
ret = spi_xfer_rx_packet(ds, din, todo);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
in_bytes -= todo;
|
||||
din += todo;
|
||||
}
|
||||
|
||||
out:
|
||||
/* Deassert CS */
|
||||
CS_change(ds->slave.bus, ds->slave.cs, CS_DEASSERT);
|
||||
|
||||
/*
|
||||
* Put the SPI Core back in the Reset State
|
||||
* to end the transfer
|
||||
*/
|
||||
(void)config_spi_state(ds, SPI_RESET_STATE);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2011 - 2014 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <delay.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/ipq_timer.h>
|
||||
#include <timer.h>
|
||||
|
||||
/*
|
||||
* DGT runs at 25 MHz / 4, or 6.25 ticks per microsecond
|
||||
*/
|
||||
#define DGT_MHZ_NUM 25
|
||||
#define DGT_MHZ_DEN 4
|
||||
|
||||
#define TIMER_TICKS(us) ((DGT_MHZ_NUM*(us) + (DGT_MHZ_DEN - 1)) / DGT_MHZ_DEN)
|
||||
#define TIMER_USECS(ticks) (DGT_MHZ_DEN*(ticks) / DGT_MHZ_NUM)
|
||||
|
||||
/* Clock divider values for the timer. */
|
||||
#define DGT_CLK_DIV_1 0
|
||||
#define DGT_CLK_DIV_2 1
|
||||
#define DGT_CLK_DIV_3 2
|
||||
#define DGT_CLK_DIV_4 3
|
||||
|
||||
/**
|
||||
* init_timer - initialize timer
|
||||
*/
|
||||
void init_timer(void)
|
||||
{
|
||||
/* disable timer */
|
||||
writel_i(0, DGT_ENABLE);
|
||||
|
||||
/* DGT uses TCXO source which is 25MHz.
|
||||
* The timer should run at 1/4th the frequency of TCXO
|
||||
* according to clock plan.
|
||||
* Set clock divider to 4.
|
||||
*/
|
||||
writel_i(DGT_CLK_DIV_4, DGT_CLK_CTL);
|
||||
|
||||
/* Enable timer */
|
||||
writel_i(0, DGT_CLEAR);
|
||||
writel_i(DGT_ENABLE_EN, DGT_ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* udelay - generates micro second delay.
|
||||
* @param usec: delay duration in microseconds
|
||||
*/
|
||||
void udelay(unsigned usec)
|
||||
{
|
||||
uint32_t now;
|
||||
uint32_t last;
|
||||
uint32_t ticks;
|
||||
uint32_t curr_ticks = 0;
|
||||
|
||||
/* Calculate number of ticks required. */
|
||||
ticks = TIMER_TICKS(usec);
|
||||
|
||||
/* Obtain the current timer value. */
|
||||
last = readl_i(DGT_COUNT_VAL);
|
||||
|
||||
/* Loop until the right number of ticks. */
|
||||
while (curr_ticks < ticks) {
|
||||
now = readl_i(DGT_COUNT_VAL);
|
||||
curr_ticks += now - last;
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
void timer_monotonic_get(struct mono_time *mt)
|
||||
{
|
||||
mono_time_set_usecs(mt, TIMER_USECS(readl_i(DGT_COUNT_VAL)));
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TZ expects the ARM core to be in 'ARM' mode. However, coreboot seems
|
||||
* to be compiled in mixed thumb/arm mode. Hence create a glue function
|
||||
* to invoke TZ.
|
||||
*/
|
||||
|
||||
#include <arch/asm.h>
|
||||
|
||||
/*
|
||||
* Force ARM mode. Else this gets assembled with mixed ARM and
|
||||
* Thumb instructions. We set up everything and jump to TZBSP
|
||||
* using the 'blx' instruction. For 'blx' if the last bit of the
|
||||
* destination address is zero, it switches to ARM mode. Since,
|
||||
* we are already in ARM mode, nothing to switch as such.
|
||||
*
|
||||
* However, when TZBSP returns, the CPU is still in ARM mode.
|
||||
* If the assembler inserts Thumb instructions between the point
|
||||
* of return from TZBSP to the 'bx' instruction we are hosed.
|
||||
* Hence forcing ARM mode.
|
||||
*
|
||||
* Rest of the code can be compiled in mixed ARM/Thumb mode.
|
||||
* Since tz_init_wrapper is being forced as an ARM symbol,
|
||||
* callers will use 'blx' to come here forcing a switch to
|
||||
* ARM mode. The wrapper does its job and returns back to the
|
||||
* Thumb caller.
|
||||
*/
|
||||
.arm
|
||||
/*
|
||||
* int tz_init_wrapper(int, int, void *);
|
||||
*/
|
||||
ENTRY(tz_init_wrapper)
|
||||
.global tz_init_wrapper
|
||||
|
||||
/*
|
||||
* r0 = tz_arg1
|
||||
* r1 = tz_arg2
|
||||
* r2 = tz_load_addr
|
||||
*/
|
||||
|
||||
/*
|
||||
* Per the AAPCS
|
||||
* r0, r1, r2, r3, r12 can be clobbered
|
||||
* r4, r5, r6, r7, r8, r9, r10, r11 have to be preserved
|
||||
*
|
||||
* Following code clobbers
|
||||
* r0 - Setting return value to zero
|
||||
* r1 - For doing a thumb return
|
||||
* r3 - Passing 'SP' from current mode to 'svc' mode
|
||||
* r4 - To save & restore CPSR
|
||||
*
|
||||
* Per AAPCS, save and restore r4, rest are 'clobberable' :)
|
||||
* The invoked code takes care of saving and restoring the other
|
||||
* preserved registers (i.e. r5 - r11)
|
||||
*
|
||||
* Stack Usage:
|
||||
* SP -> | LR | (Lower address)
|
||||
* | r4 |
|
||||
* | CPSR |
|
||||
* |-------|
|
||||
* | . |
|
||||
* | . |
|
||||
* | . | (Higher address)
|
||||
*/
|
||||
|
||||
sub sp, sp, #12 /* Allocate stack frame */
|
||||
str lr, [sp] /* Save return address */
|
||||
str r4, [sp, #4] /* Use r4 to hold the new CPSR value */
|
||||
|
||||
mov r3, sp /* Get current stack pointer */
|
||||
|
||||
mrs r4, CPSR /* save CPSR */
|
||||
str r4, [sp, #8]
|
||||
|
||||
bic r4, r4, 0x1f /* Clear mode bits */
|
||||
orr r4, r4, 0x13 /* 'svc' mode */
|
||||
msr cpsr_cxf, r4 /* Switch to Supervisor mode. */
|
||||
mov sp, r3 /* Use the same stack as the previous mode */
|
||||
|
||||
blx r2 /* Jump to TZ in ARM mode */
|
||||
|
||||
nop /* back from TZ, in ARM mode */
|
||||
|
||||
ldr r4, [sp, #8] /* restore CPSR */
|
||||
msr cpsr_cxf, r4
|
||||
|
||||
ldr r4, [sp, #4] /* restore r4 */
|
||||
|
||||
ldr lr, [sp] /* saved return address */
|
||||
add sp, sp, #12 /* free stack frame */
|
||||
|
||||
bx lr /* back to thumb caller */
|
||||
|
||||
ENDPROC(tz_init_wrapper)
|
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
* Copyright (c) 2012 The Linux Foundation. All rights reserved.
|
||||
* Source : APQ8064 LK boot
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <boot/coreboot_tables.h>
|
||||
#include <console/console.h>
|
||||
#include <console/uart.h>
|
||||
#include <delay.h>
|
||||
#include <gpio.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/gsbi.h>
|
||||
#include <soc/ipq_uart.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FIFO_DATA_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
void *uart_dm_base;
|
||||
void *uart_gsbi_base;
|
||||
unsigned uart_gsbi;
|
||||
uart_clk_mnd_t mnd_value;
|
||||
gpio_func_data_t dbg_uart_gpio[NO_OF_DBG_UART_GPIOS];
|
||||
} uart_params_t;
|
||||
|
||||
/*
|
||||
* All constants lifted from u-boot's
|
||||
* board/qcom/ipq40xx_cdp/ipq40xx_board_param.h
|
||||
*/
|
||||
static const uart_params_t uart_board_param = {
|
||||
.uart_dm_base = (void *)UART4_DM_BASE,
|
||||
.uart_gsbi_base = (void *)UART_GSBI4_BASE,
|
||||
.uart_gsbi = GSBI_4,
|
||||
.mnd_value = { 12, 625, 313 },
|
||||
.dbg_uart_gpio = {
|
||||
{
|
||||
.gpio = 10,
|
||||
.func = 1,
|
||||
.dir = GPIO_OUTPUT,
|
||||
.pull = GPIO_NO_PULL,
|
||||
.drvstr = GPIO_12MA,
|
||||
.enable = GPIO_DISABLE
|
||||
},
|
||||
{
|
||||
.gpio = 11,
|
||||
.func = 1,
|
||||
.dir = GPIO_INPUT,
|
||||
.pull = GPIO_NO_PULL,
|
||||
.drvstr = GPIO_12MA,
|
||||
.enable = GPIO_DISABLE
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* msm_boot_uart_dm_init_rx_transfer - Init Rx transfer
|
||||
* @uart_dm_base: UART controller base address
|
||||
*/
|
||||
static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base)
|
||||
{
|
||||
/* Reset receiver */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_CMD_RESET_RX);
|
||||
|
||||
/* Enable receiver */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_CR_RX_ENABLE);
|
||||
write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_DMRX_DEF_VALUE);
|
||||
|
||||
/* Clear stale event */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
|
||||
|
||||
/* Enable stale event */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT);
|
||||
|
||||
return MSM_BOOT_UART_DM_E_SUCCESS;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRIVERS_UART)
|
||||
static unsigned int msm_boot_uart_dm_init(void *uart_dm_base);
|
||||
|
||||
/* Received data is valid or not */
|
||||
static int valid_data = 0;
|
||||
|
||||
/* Received data */
|
||||
static unsigned int word = 0;
|
||||
|
||||
/**
|
||||
* msm_boot_uart_dm_read - reads a word from the RX FIFO.
|
||||
* @data: location where the read data is stored
|
||||
* @count: no of valid data in the FIFO
|
||||
* @wait: indicates blocking call or not blocking call
|
||||
*
|
||||
* Reads a word from the RX FIFO. If no data is available blocks if
|
||||
* @wait is true, else returns %MSM_BOOT_UART_DM_E_RX_NOT_READY.
|
||||
*/
|
||||
#if 0 /* Not used yet */
|
||||
static unsigned int
|
||||
msm_boot_uart_dm_read(unsigned int *data, int *count, int wait)
|
||||
{
|
||||
static int total_rx_data = 0;
|
||||
static int rx_data_read = 0;
|
||||
void *base;
|
||||
uint32_t status_reg;
|
||||
|
||||
base = uart_board_param.uart_dm_base;
|
||||
|
||||
if (data == NULL)
|
||||
return MSM_BOOT_UART_DM_E_INVAL;
|
||||
|
||||
status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
|
||||
|
||||
/* Check for DM_RXSTALE for RX transfer to finish */
|
||||
while (!(status_reg & MSM_BOOT_UART_DM_RXSTALE)) {
|
||||
status_reg = readl(MSM_BOOT_UART_DM_MISR(base));
|
||||
if (!wait)
|
||||
return MSM_BOOT_UART_DM_E_RX_NOT_READY;
|
||||
}
|
||||
|
||||
/* Check for Overrun error. We'll just reset Error Status */
|
||||
if (readl(MSM_BOOT_UART_DM_SR(base)) &
|
||||
MSM_BOOT_UART_DM_SR_UART_OVERRUN) {
|
||||
writel(MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT,
|
||||
MSM_BOOT_UART_DM_CR(base));
|
||||
total_rx_data = rx_data_read = 0;
|
||||
msm_boot_uart_dm_init(base);
|
||||
return MSM_BOOT_UART_DM_E_RX_NOT_READY;
|
||||
}
|
||||
|
||||
/* Read UART_DM_RX_TOTAL_SNAP for actual number of bytes received */
|
||||
if (total_rx_data == 0)
|
||||
total_rx_data = readl(MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base));
|
||||
|
||||
/* Data available in FIFO; read a word. */
|
||||
*data = readl(MSM_BOOT_UART_DM_RF(base, 0));
|
||||
|
||||
/* WAR for http://prism/CR/548280 */
|
||||
if (*data == 0)
|
||||
return MSM_BOOT_UART_DM_E_RX_NOT_READY;
|
||||
|
||||
/* increment the total count of chars we've read so far */
|
||||
rx_data_read += FIFO_DATA_SIZE;
|
||||
|
||||
/* actual count of valid data in word */
|
||||
*count = ((total_rx_data < rx_data_read) ?
|
||||
(FIFO_DATA_SIZE - (rx_data_read - total_rx_data)) :
|
||||
FIFO_DATA_SIZE);
|
||||
|
||||
/* If there are still data left in FIFO we'll read them before
|
||||
* initializing RX Transfer again
|
||||
*/
|
||||
if (rx_data_read < total_rx_data)
|
||||
return MSM_BOOT_UART_DM_E_SUCCESS;
|
||||
|
||||
msm_boot_uart_dm_init_rx_transfer(base);
|
||||
total_rx_data = rx_data_read = 0;
|
||||
|
||||
return MSM_BOOT_UART_DM_E_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
void uart_tx_byte(int idx, unsigned char data)
|
||||
{
|
||||
int num_of_chars = 1;
|
||||
unsigned tx_data = 0;
|
||||
void *base = uart_board_param.uart_dm_base;
|
||||
|
||||
/* Wait until transmit FIFO is empty. */
|
||||
while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
|
||||
MSM_BOOT_UART_DM_SR_TXEMT))
|
||||
udelay(1);
|
||||
/*
|
||||
* TX FIFO is ready to accept new character(s). First write number of
|
||||
* characters to be transmitted.
|
||||
*/
|
||||
write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base), num_of_chars);
|
||||
|
||||
/* And now write the character(s) */
|
||||
write32(MSM_BOOT_UART_DM_TF(base, 0), tx_data);
|
||||
}
|
||||
#endif /* CONFIG_SERIAL_UART */
|
||||
|
||||
/*
|
||||
* msm_boot_uart_dm_reset - resets UART controller
|
||||
* @base: UART controller base address
|
||||
*/
|
||||
static unsigned int msm_boot_uart_dm_reset(void *base)
|
||||
{
|
||||
write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_RX);
|
||||
write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_TX);
|
||||
write32(MSM_BOOT_UART_DM_CR(base),
|
||||
MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT);
|
||||
write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_TX_ERR);
|
||||
write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_STALE_INT);
|
||||
|
||||
return MSM_BOOT_UART_DM_E_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* msm_boot_uart_dm_init - initilaizes UART controller
|
||||
* @uart_dm_base: UART controller base address
|
||||
*/
|
||||
static unsigned int msm_boot_uart_dm_init(void *uart_dm_base)
|
||||
{
|
||||
/* Configure UART mode registers MR1 and MR2 */
|
||||
/* Hardware flow control isn't supported */
|
||||
write32(MSM_BOOT_UART_DM_MR1(uart_dm_base), 0x0);
|
||||
|
||||
/* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */
|
||||
write32(MSM_BOOT_UART_DM_MR2(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_8_N_1_MODE);
|
||||
|
||||
/* Configure Interrupt Mask register IMR */
|
||||
write32(MSM_BOOT_UART_DM_IMR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_IMR_ENABLED);
|
||||
|
||||
/*
|
||||
* Configure Tx and Rx watermarks configuration registers
|
||||
* TX watermark value is set to 0 - interrupt is generated when
|
||||
* FIFO level is less than or equal to 0
|
||||
*/
|
||||
write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_TFW_VALUE);
|
||||
|
||||
/* RX watermark value */
|
||||
write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_RFW_VALUE);
|
||||
|
||||
/* Configure Interrupt Programming Register */
|
||||
/* Set initial Stale timeout value */
|
||||
write32(MSM_BOOT_UART_DM_IPR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB);
|
||||
|
||||
/* Configure IRDA if required */
|
||||
/* Disabling IRDA mode */
|
||||
write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0);
|
||||
|
||||
/* Configure hunt character value in HCR register */
|
||||
/* Keep it in reset state */
|
||||
write32(MSM_BOOT_UART_DM_HCR(uart_dm_base), 0x0);
|
||||
|
||||
/*
|
||||
* Configure Rx FIFO base address
|
||||
* Both TX/RX shares same SRAM and default is half-n-half.
|
||||
* Sticking with default value now.
|
||||
* As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries).
|
||||
* We have found RAM_ADDR_WIDTH = 0x7f
|
||||
*/
|
||||
|
||||
/* Issue soft reset command */
|
||||
msm_boot_uart_dm_reset(uart_dm_base);
|
||||
|
||||
/* Enable/Disable Rx/Tx DM interfaces */
|
||||
/* Data Mover not currently utilized. */
|
||||
write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0);
|
||||
|
||||
/* Enable transmitter */
|
||||
write32(MSM_BOOT_UART_DM_CR(uart_dm_base),
|
||||
MSM_BOOT_UART_DM_CR_TX_ENABLE);
|
||||
|
||||
/* Initialize Receive Path */
|
||||
msm_boot_uart_dm_init_rx_transfer(uart_dm_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipq40xx_uart_init - initializes UART
|
||||
*
|
||||
* Initializes clocks, GPIO and UART controller.
|
||||
*/
|
||||
void uart_init(int idx)
|
||||
{
|
||||
/* Note int idx isn't used in this driver. */
|
||||
void *dm_base;
|
||||
void *gsbi_base;
|
||||
|
||||
dm_base = uart_board_param.uart_dm_base;
|
||||
|
||||
if (read32(MSM_BOOT_UART_DM_CSR(dm_base)) == UART_DM_CLK_RX_TX_BIT_RATE)
|
||||
return; /* UART must have been already initialized. */
|
||||
|
||||
gsbi_base = uart_board_param.uart_gsbi_base;
|
||||
ipq_configure_gpio(uart_board_param.dbg_uart_gpio,
|
||||
NO_OF_DBG_UART_GPIOS);
|
||||
|
||||
/* Configure the uart clock */
|
||||
uart_clock_config(uart_board_param.uart_gsbi,
|
||||
uart_board_param.mnd_value.m_value,
|
||||
uart_board_param.mnd_value.n_value,
|
||||
uart_board_param.mnd_value.d_value,
|
||||
0);
|
||||
|
||||
write32(GSBI_CTRL_REG(gsbi_base),
|
||||
GSBI_PROTOCOL_CODE_I2C_UART << GSBI_CTRL_REG_PROTOCOL_CODE_S);
|
||||
write32(MSM_BOOT_UART_DM_CSR(dm_base), UART_DM_CLK_RX_TX_BIT_RATE);
|
||||
|
||||
/* Initialize UART_DM */
|
||||
msm_boot_uart_dm_init(dm_base);
|
||||
}
|
||||
|
||||
/* for the benefit of non-console uart init */
|
||||
void ipq40xx_uart_init(void)
|
||||
{
|
||||
uart_init(0);
|
||||
}
|
||||
|
||||
#if 0 /* Not used yet */
|
||||
uint32_t uartmem_getbaseaddr(void)
|
||||
{
|
||||
return (uint32_t)uart_board_param.uart_dm_base;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* uart_tx_flush - transmits a string of data
|
||||
* @s: string to transmit
|
||||
*/
|
||||
void uart_tx_flush(int idx)
|
||||
{
|
||||
void *base = uart_board_param.uart_dm_base;
|
||||
|
||||
while (!(read32(MSM_BOOT_UART_DM_SR(base)) &
|
||||
MSM_BOOT_UART_DM_SR_TXEMT))
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* uart_can_rx_byte - checks if data available for reading
|
||||
*
|
||||
* Returns 1 if data available, 0 otherwise
|
||||
*/
|
||||
#if 0 /* Not used yet */
|
||||
int uart_can_rx_byte(void)
|
||||
{
|
||||
/* Return if data is already read */
|
||||
if (valid_data)
|
||||
return 1;
|
||||
|
||||
/* Read data from the FIFO */
|
||||
if (msm_boot_uart_dm_read(&word, &valid_data, 0) !=
|
||||
MSM_BOOT_UART_DM_E_SUCCESS)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRIVERS_UART)
|
||||
/**
|
||||
* ipq40xx_serial_getc - reads a character
|
||||
*
|
||||
* Returns the character read from serial port.
|
||||
*/
|
||||
uint8_t uart_rx_byte(int idx)
|
||||
{
|
||||
uint8_t byte;
|
||||
|
||||
#if 0 /* Not used yet */
|
||||
while (!uart_can_rx_byte())
|
||||
; /* wait for incoming data */
|
||||
#endif
|
||||
byte = (uint8_t)(word & 0xff);
|
||||
word = word >> 8;
|
||||
valid_data--;
|
||||
|
||||
return byte;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __PRE_RAM__
|
||||
/* TODO: Implement function */
|
||||
void uart_fill_lb(void *data)
|
||||
{
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* This program 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; version 2 of the License.
|
||||
*
|
||||
* This program 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.
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <console/console.h>
|
||||
#include <delay.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/usb.h>
|
||||
|
||||
#define CRPORT_TX_OVRD_DRV_LO 0x1002
|
||||
#define CRPORT_RX_OVRD_IN_HI 0x1006
|
||||
#define CRPORT_TX_ALT_BLOCK 0x102d
|
||||
|
||||
static u32 * const tcsr_usb_sel = (void *)0x1a4000b0;
|
||||
|
||||
struct usb_qc_phy {
|
||||
u32 ipcat;
|
||||
u32 ctrl;
|
||||
u32 general_cfg;
|
||||
u32 ram1;
|
||||
u32 hs_phy_ctrl;
|
||||
u32 param_ovrd;
|
||||
u32 chrg_det_ctrl;
|
||||
u32 chrg_det_output;
|
||||
u32 alt_irq_en;
|
||||
u32 hs_phy_irq_stat;
|
||||
u32 cgctl;
|
||||
u32 dbg_bus;
|
||||
u32 ss_phy_ctrl;
|
||||
u32 ss_phy_param1;
|
||||
u32 ss_phy_param2;
|
||||
u32 crport_data_in;
|
||||
u32 crport_data_out;
|
||||
u32 crport_cap_addr;
|
||||
u32 crport_cap_data;
|
||||
u32 crport_ack_read;
|
||||
u32 crport_ack_write;
|
||||
};
|
||||
check_member(usb_qc_phy, crport_ack_write, 0x50);
|
||||
|
||||
static struct usb_qc_phy * const usb_host1_phy = (void *)USB_HOST1_PHY_BASE;
|
||||
static struct usb_qc_phy * const usb_host2_phy = (void *)USB_HOST2_PHY_BASE;
|
||||
|
||||
struct usb_dwc3 {
|
||||
u32 sbuscfg0;
|
||||
u32 sbuscfg1;
|
||||
u32 txthrcfg;
|
||||
u32 rxthrcfg;
|
||||
u32 ctl;
|
||||
u32 evten;
|
||||
u32 sts;
|
||||
u8 reserved0[4];
|
||||
u32 snpsid;
|
||||
u32 gpio;
|
||||
u32 uid;
|
||||
u32 uctl;
|
||||
u64 buserraddr;
|
||||
u64 prtbimap;
|
||||
u8 reserved1[32];
|
||||
u32 dbgfifospace;
|
||||
u32 dbgltssm;
|
||||
u32 dbglnmcc;
|
||||
u32 dbgbmu;
|
||||
u32 dbglspmux;
|
||||
u32 dbglsp;
|
||||
u32 dbgepinfo0;
|
||||
u32 dbgepinfo1;
|
||||
u64 prtbimap_hs;
|
||||
u64 prtbimap_fs;
|
||||
u8 reserved2[112];
|
||||
u32 usb2phycfg;
|
||||
u8 reserved3[60];
|
||||
u32 usb2i2cctl;
|
||||
u8 reserved4[60];
|
||||
u32 usb2phyacc;
|
||||
u8 reserved5[60];
|
||||
u32 usb3pipectl;
|
||||
u8 reserved6[60];
|
||||
};
|
||||
check_member(usb_dwc3, usb3pipectl, 0x1c0);
|
||||
|
||||
static struct usb_dwc3 * const usb_host1_dwc3 = (void *)USB_HOST1_DWC3_BASE;
|
||||
static struct usb_dwc3 * const usb_host2_dwc3 = (void *)USB_HOST2_DWC3_BASE;
|
||||
|
||||
static void setup_dwc3(struct usb_dwc3 *dwc3)
|
||||
{
|
||||
write32(&dwc3->usb3pipectl,
|
||||
0x1 << 31 | /* assert PHY soft reset */
|
||||
0x1 << 25 | /* (default) U1/U2 exit fail -> recovery? */
|
||||
0x1 << 24 | /* (default) activate PHY low power states */
|
||||
0x1 << 19 | /* (default) PHY low power delay value */
|
||||
0x1 << 18 | /* (default) activate PHY low power delay */
|
||||
0x1 << 1 | /* (default) Tx deemphasis value */
|
||||
0x1 << 0); /* (default) elastic buffer mode */
|
||||
|
||||
write32(&dwc3->usb2phycfg,
|
||||
0x1 << 31 | /* assert PHY soft reset */
|
||||
0x9 << 10 | /* (default) PHY clock turnaround 8-bit UTMI+ */
|
||||
0x1 << 8 | /* (default) enable PHY sleep in L1 */
|
||||
0x1 << 6); /* (default) enable PHY suspend */
|
||||
|
||||
write32(&dwc3->ctl,
|
||||
0x2 << 19 | /* (default) suspend clock scaling */
|
||||
0x1 << 16 | /* retry SS three times before HS downgrade */
|
||||
0x1 << 12 | /* port capability HOST */
|
||||
0x1 << 11 | /* assert core soft reset */
|
||||
0x1 << 10 | /* (default) sync ITP to refclk */
|
||||
0x1 << 2); /* U2 exit after 8us LFPS (instead of 248ns) */
|
||||
|
||||
write32(&dwc3->uctl,
|
||||
0x32 << 22 | /* (default) reference clock period in ns */
|
||||
0x1 << 15 | /* (default) XHCI compliant device addressing */
|
||||
0x10 << 0); /* (default) devices time out after 32us */
|
||||
|
||||
udelay(5);
|
||||
|
||||
clrbits_le32(&dwc3->ctl, 0x1 << 11); /* deassert core soft reset */
|
||||
clrbits_le32(&dwc3->usb2phycfg, 0x1 << 31); /* PHY soft reset */
|
||||
clrbits_le32(&dwc3->usb3pipectl, 0x1 << 31); /* PHY soft reset */
|
||||
}
|
||||
|
||||
static void setup_phy(struct usb_qc_phy *phy)
|
||||
{
|
||||
write32(&phy->ss_phy_ctrl,
|
||||
0x1 << 24 | /* Indicate VBUS power present */
|
||||
0x1 << 8 | /* Enable USB3 ref clock to prescaler */
|
||||
0x1 << 7 | /* assert SS PHY reset */
|
||||
0x19 << 0); /* (default) reference clock multiplier */
|
||||
|
||||
write32(&phy->hs_phy_ctrl,
|
||||
0x1 << 26 | /* (default) unclamp DPSE/DMSE VLS */
|
||||
0x1 << 25 | /* (default) select freeclk for utmi_clk */
|
||||
0x1 << 24 | /* (default) unclamp DMSE VLS */
|
||||
0x1 << 21 | /* (default) enable UTMI clock */
|
||||
0x1 << 20 | /* set OTG VBUS as valid */
|
||||
0x1 << 18 | /* use ref clock from core */
|
||||
0x1 << 17 | /* (default) unclamp DPSE VLS */
|
||||
0x1 << 11 | /* force xo/bias/pll to stay on in suspend */
|
||||
0x1 << 9 | /* (default) unclamp IDHV */
|
||||
0x1 << 8 | /* (default) unclamp VLS (again???) */
|
||||
0x1 << 7 | /* (default) unclamp HV VLS */
|
||||
0x7 << 4 | /* select frequency (no idea which one) */
|
||||
0x1 << 1); /* (default) "retention enable" */
|
||||
|
||||
write32(&phy->ss_phy_param1,
|
||||
0x6e << 20 | /* full TX swing amplitude */
|
||||
0x20 << 14 | /* (default) 6dB TX deemphasis */
|
||||
0x17 << 8 | /* 3.5dB TX deemphasis */
|
||||
0x9 << 3); /* (default) LoS detector level */
|
||||
|
||||
write32(&phy->general_cfg, 0x1 << 2); /* set XHCI 1.00 compliance */
|
||||
|
||||
udelay(5);
|
||||
clrbits_le32(&phy->ss_phy_ctrl, 0x1 << 7); /* deassert SS PHY reset */
|
||||
}
|
||||
|
||||
static void crport_handshake(void *capture_reg, void *acknowledge_bit, u32 data)
|
||||
{
|
||||
int usec = 100;
|
||||
|
||||
if (capture_reg)
|
||||
write32(capture_reg, data);
|
||||
|
||||
write32(acknowledge_bit, 0x1 << 0);
|
||||
while (read32(acknowledge_bit) && --usec)
|
||||
udelay(1);
|
||||
|
||||
if (!usec)
|
||||
printk(BIOS_ERR, "CRPORT handshake timed out (0x%08x)\n", data);
|
||||
}
|
||||
|
||||
static void crport_write(struct usb_qc_phy *phy, u16 addr, u16 data)
|
||||
{
|
||||
crport_handshake(&phy->crport_data_in, &phy->crport_cap_addr, addr);
|
||||
crport_handshake(&phy->crport_data_in, &phy->crport_cap_data, data);
|
||||
crport_handshake(NULL, &phy->crport_ack_write, 0);
|
||||
}
|
||||
|
||||
static void tune_phy(struct usb_qc_phy *phy)
|
||||
{
|
||||
crport_write(phy, CRPORT_RX_OVRD_IN_HI,
|
||||
0x1 << 11 | /* Set RX_EQ override? */
|
||||
0x4 << 8 | /* Set RX_EQ to 4? */
|
||||
0x1 << 7); /* Enable RX_EQ override */
|
||||
crport_write(phy, CRPORT_TX_OVRD_DRV_LO,
|
||||
0x1 << 14 | /* Enable amplitude (override?) */
|
||||
0x17 << 7 | /* Set TX deemphasis to 23 */
|
||||
0x6e << 0); /* Set amplitude to 110 */
|
||||
crport_write(phy, CRPORT_TX_ALT_BLOCK,
|
||||
0x1 << 7); /* ALT block? ("partial RX reset") */
|
||||
}
|
||||
|
||||
void setup_usb_host1(void)
|
||||
{
|
||||
printk(BIOS_INFO, "Setting up USB HOST1 controller...\n");
|
||||
setbits_le32(tcsr_usb_sel, 1 << 0); /* Select DWC3 controller */
|
||||
setup_phy(usb_host1_phy);
|
||||
setup_dwc3(usb_host1_dwc3);
|
||||
tune_phy(usb_host1_phy);
|
||||
}
|
||||
|
||||
void setup_usb_host2(void)
|
||||
{
|
||||
printk(BIOS_INFO, "Setting up USB HOST2 controller...\n");
|
||||
setbits_le32(tcsr_usb_sel, 1 << 1); /* Select DWC3 controller */
|
||||
setup_phy(usb_host2_phy);
|
||||
setup_dwc3(usb_host2_dwc3);
|
||||
tune_phy(usb_host2_phy);
|
||||
}
|
Loading…
Reference in New Issue