MSM8916Pkg: Implement clocks

Signed-off-by: Ivaylo Ivanov <ivo.ivanov@null.net>
Cc: Bingxing Wang <hi@imbushuo.net> (nice email)
This commit is contained in:
Ivaylo Ivanov 2021-09-02 16:09:08 +03:00
parent 7e44ba1051
commit c2681ce7d9
31 changed files with 3297 additions and 1 deletions

View File

@ -0,0 +1,35 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ClockDxe
FILE_GUID = 3EBA1869-45CA-41E1-AD6B-40BA8012A538
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = ClockDxeInitialize
[Sources.common]
Driver.c
LibraryImpl.c
clock.c
clock_lib2.c
clock-local.c
clock_pll.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
UefiDriverEntryPoint
QcomPlatformClockInitLib
TimerLib
[BuildOptions.AARCH64]
GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-overflow
[Protocols]
gQcomClockProtocolGuid
[Depex]
TRUE

View File

@ -0,0 +1,26 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ClockImplLib
FILE_GUID = 44790987-E75E-4178-AE98-AC961D33D8FE
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ClockLib
CONSTRUCTOR = ClockImplLibInitialize
[Sources.common]
LibraryImpl.c
clock.c
clock_lib2.c
clock-local.c
clock_pll.c
[BuildOptions.AARCH64]
GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-overflow
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
QcomPlatformClockInitLib

View File

@ -0,0 +1,28 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ClockLib
FILE_GUID = 84B9E8B0-E69E-451A-8520-0BDBFDCE2364
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ClockLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER
CONSTRUCTOR = ClockLibConstructor
[Sources.common]
LibraryBS.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
UefiBootServicesTableLib
[BuildOptions.AARCH64]
GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-overflow
[Protocols]
gQcomClockProtocolGuid
[Depex]
gQcomClockProtocolGuid

View File

@ -0,0 +1,22 @@
#include <PiDxe.h>
#include <Library/LKEnvLib.h>
#include <Library/QcomClockLib.h>
#include <Library/UefiBootServicesTableLib.h>
EFI_STATUS
EFIAPI
ClockDxeInitialize(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
{
EFI_HANDLE Handle = NULL;
EFI_STATUS Status;
ClockImplLibInitialize();
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle, &gQcomClockProtocolGuid, gClock, NULL);
ASSERT_EFI_ERROR(Status);
return Status;
}

View File

@ -0,0 +1,20 @@
#include <PiDxe.h>
#include <Library/LKEnvLib.h>
#include <Library/QcomClockLib.h>
#include <Library/UefiBootServicesTableLib.h>
QCOM_CLOCK_PROTOCOL *gClock = NULL;
RETURN_STATUS
EFIAPI
ClockLibConstructor(VOID)
{
EFI_STATUS Status;
Status = gBS->LocateProtocol(&gQcomClockProtocolGuid, NULL, (VOID **)&gClock);
ASSERT_EFI_ERROR(Status);
return Status;
}

View File

@ -0,0 +1,33 @@
#include <Base.h>
#include <Library/LKEnvLib.h>
#include <Library/QcomClockLib.h>
#include <Library/QcomPlatformClockInitLib.h>
#include "clock_p.h"
QCOM_CLOCK_PROTOCOL *gClock = NULL;
STATIC QCOM_CLOCK_PROTOCOL mInternalClock = {
clk_get, clk_enable, clk_disable,
clk_get_rate, clk_set_rate, clk_set_parent,
clk_get_parent, clk_get_set_enable, clk_reset,
};
RETURN_STATUS
EFIAPI
ClockImplLibInitialize(VOID)
{
EFI_STATUS Status;
struct clk_lookup *clist = NULL;
unsigned num = 0;
gClock = &mInternalClock;
Status = LibQcomPlatformClockInit(&clist, &num);
ASSERT_EFI_ERROR(Status);
clk_init(clist, num);
return Status;
}

View File

@ -0,0 +1,3 @@
URL: https://source.codeaurora.org/quic/la/kernel/lk
BRANCH: LA.AF.1.1-02810-8064.0
UPDATED FROM: LA.BF64.1.2.3-01510-8x94.0

View File

@ -0,0 +1,387 @@
/*
* 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 <Library/LKEnvLib.h>
#include <Chipset/clock.h>
// Must come in order
#include <Chipset/clock-local.h>
#include "clock_p.h"
/*
* When enabling/disabling a clock, check the halt bit up to this number
* number of times (with a 1 us delay in between) before continuing.
*/
#define HALT_CHECK_MAX_LOOPS 100
/* For clock without halt checking, wait this long after enables/disables. */
#define HALT_CHECK_DELAY_US 10
struct clk_freq_tbl local_dummy_freq = F_END;
/*
* Clock enable/disable functions
*/
static int branch_clk_is_halted(const struct branch *clk)
{
int invert = (clk->halt_check == ENABLE);
int status_bit = readl_relaxed(clk->halt_reg) & BIT(clk->halt_bit);
return invert ? !status_bit : status_bit;
}
static void __branch_clk_enable_reg(const struct branch *clk, const char *name)
{
uint32_t reg_val;
if (clk->en_mask) {
reg_val = readl_relaxed(clk->ctl_reg);
reg_val |= clk->en_mask;
writel_relaxed(reg_val, clk->ctl_reg);
}
/* Wait for clock to enable before returning. */
if (clk->halt_check == DELAY)
udelay(HALT_CHECK_DELAY_US);
else if (
clk->halt_check == ENABLE || clk->halt_check == HALT ||
clk->halt_check == ENABLE_VOTED || clk->halt_check == HALT_VOTED) {
int count;
/* Wait up to HALT_CHECK_MAX_LOOPS for clock to enable. */
for (count = HALT_CHECK_MAX_LOOPS; branch_clk_is_halted(clk) && count > 0;
count--)
udelay(1);
}
}
/* Perform any register operations required to enable the clock. */
static void __local_clk_enable_reg(struct rcg_clk *clk)
{
uint32_t reg_val;
void *const reg = clk->b.ctl_reg;
if (clk->current_freq == &local_dummy_freq)
dprintf(
CRITICAL, "Attempting to enable %s before setting its rate.",
clk->c.dbg_name);
/*
* 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.
*/
if (clk->ns_mask) {
reg_val = readl_relaxed(clk->ns_reg);
reg_val &= ~(clk->ns_mask);
reg_val |= (clk->current_freq->ns_val & clk->ns_mask);
writel_relaxed(reg_val, clk->ns_reg);
}
/* Enable MN counter, if applicable. */
reg_val = readl_relaxed(reg);
if (clk->current_freq->mnd_en_mask) {
reg_val |= clk->current_freq->mnd_en_mask;
writel_relaxed(reg_val, reg);
}
/* Enable root. */
if (clk->root_en_mask) {
reg_val |= clk->root_en_mask;
writel_relaxed(reg_val, reg);
}
__branch_clk_enable_reg(&clk->b, clk->c.dbg_name);
}
/* Enable a clock and any related power rail. */
int local_clk_enable(struct clk *c)
{
int rc;
struct rcg_clk *clk = to_rcg_clk(c);
rc = clk_enable(clk->depends);
if (rc)
goto err_dep;
__local_clk_enable_reg(clk);
clk->enabled = true;
err_dep:
return rc;
}
/* Disable a clock and any related power rail. */
void local_clk_disable(struct clk *c)
{ /*TODO: Stub function for now.*/
}
/*
* Frequency-related functions
*/
/* Set a clock's frequency. */
static int _local_clk_set_rate(struct rcg_clk *clk, struct clk_freq_tbl *nf)
{
struct clk_freq_tbl *cf;
int rc = 0;
/* Check if frequency is actually changed. */
cf = clk->current_freq;
if (nf == cf)
goto unlock;
if (clk->enabled) {
rc = clk_enable(nf->src_clk);
if (rc) {
goto unlock;
}
}
/* Perform clock-specific frequency switch operations. */
ASSERT(clk->set_rate);
clk->set_rate(clk, nf);
/*
* Current freq must be updated before __local_clk_enable_reg()
* is called to make sure the MNCNTR_EN bit is set correctly.
*/
clk->current_freq = nf;
/* Enable any clocks that were disabled. */
if (clk->bank_masks == NULL) {
if (clk->enabled)
__local_clk_enable_reg(clk);
}
unlock:
return rc;
}
/* Set a clock to an exact rate. */
int local_clk_set_rate(struct clk *c, unsigned rate)
{
struct rcg_clk * clk = to_rcg_clk(c);
struct clk_freq_tbl *nf;
for (nf = clk->freq_tbl; nf->freq_hz != FREQ_END && nf->freq_hz != rate; nf++)
;
if (nf->freq_hz == FREQ_END)
return ERR_INVALID_ARGS;
return _local_clk_set_rate(clk, nf);
}
/* Get the currently-set rate of a clock in Hz. */
unsigned local_clk_get_rate(struct clk *c)
{
/* TODO: Stub function for now. */
return 0;
}
/* Check if a clock is currently enabled. */
int local_clk_is_enabled(struct clk *clk) { return to_rcg_clk(clk)->enabled; }
/* Return a supported rate that's at least the specified rate. */
long local_clk_round_rate(struct clk *c, unsigned rate)
{
struct rcg_clk * clk = to_rcg_clk(c);
struct clk_freq_tbl *f;
for (f = clk->freq_tbl; f->freq_hz != FREQ_END; f++)
if (f->freq_hz >= rate)
return f->freq_hz;
return ERR_INVALID_ARGS;
}
struct clk *local_clk_get_parent(struct clk *clk)
{
return to_rcg_clk(clk)->current_freq->src_clk;
}
/*
* Branch clocks functions
*/
int branch_clk_enable(struct clk *clk)
{
struct branch_clk *branch = to_branch_clk(clk);
__branch_clk_enable_reg(&branch->b, branch->c.dbg_name);
branch->enabled = true;
return 0;
}
void branch_clk_disable(struct clk *clk)
{ /* TODO: Stub function for now */
}
struct clk *branch_clk_get_parent(struct clk *clk)
{
struct branch_clk *branch = to_branch_clk(clk);
return branch->parent;
}
int branch_clk_set_parent(struct clk *clk, struct clk *parent)
{
/* This is a stub function. */
return 0;
}
int branch_clk_is_enabled(struct clk *clk)
{
struct branch_clk *branch = to_branch_clk(clk);
return branch->enabled;
}
/**/
/* For clocks with MND dividers. */
void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf)
{
uint32_t ns_reg_val, ctl_reg_val;
/* Assert MND reset. */
ns_reg_val = readl_relaxed(clk->ns_reg);
ns_reg_val |= BIT(7);
writel_relaxed(ns_reg_val, clk->ns_reg);
/* Program M and D values. */
writel_relaxed(nf->md_val, clk->md_reg);
/* If the clock has a separate CC register, program it. */
if (clk->ns_reg != clk->b.ctl_reg) {
ctl_reg_val = readl_relaxed(clk->b.ctl_reg);
ctl_reg_val &= ~(clk->ctl_mask);
ctl_reg_val |= nf->ctl_val;
writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
}
/* Deassert MND reset. */
ns_reg_val &= ~BIT(7);
writel_relaxed(ns_reg_val, clk->ns_reg);
}
void set_rate_mnd_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf)
{
struct bank_masks * banks = clk->bank_masks;
const struct bank_mask_info *new_bank_masks;
const struct bank_mask_info *old_bank_masks;
uint32_t ns_reg_val, ctl_reg_val;
uint32_t bank_sel;
/*
* Determine active bank and program the other one. If the clock is
* off, program the active bank since bank switching won't work if
* both banks aren't running.
*/
ctl_reg_val = readl_relaxed(clk->b.ctl_reg);
bank_sel = !!(ctl_reg_val & banks->bank_sel_mask);
/* If clock isn't running, don't switch banks. */
bank_sel ^= (!clk->enabled || clk->current_freq->freq_hz == 0);
if (bank_sel == 0) {
new_bank_masks = &banks->bank1_mask;
old_bank_masks = &banks->bank0_mask;
}
else {
new_bank_masks = &banks->bank0_mask;
old_bank_masks = &banks->bank1_mask;
}
ns_reg_val = readl_relaxed(clk->ns_reg);
/* Assert bank MND reset. */
ns_reg_val |= new_bank_masks->rst_mask;
writel_relaxed(ns_reg_val, clk->ns_reg);
/*
* Program NS only if the clock is enabled, since the NS will be set
* as part of the enable procedure and should remain with a low-power
* MUX input selected until then.
*/
if (clk->enabled) {
ns_reg_val &= ~(new_bank_masks->ns_mask);
ns_reg_val |= (nf->ns_val & new_bank_masks->ns_mask);
writel_relaxed(ns_reg_val, clk->ns_reg);
}
writel_relaxed(nf->md_val, new_bank_masks->md_reg);
/* Enable counter only if clock is enabled. */
if (clk->enabled)
ctl_reg_val |= new_bank_masks->mnd_en_mask;
else
ctl_reg_val &= ~(new_bank_masks->mnd_en_mask);
ctl_reg_val &= ~(new_bank_masks->mode_mask);
ctl_reg_val |= (nf->ctl_val & new_bank_masks->mode_mask);
writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
/* Deassert bank MND reset. */
ns_reg_val &= ~(new_bank_masks->rst_mask);
writel_relaxed(ns_reg_val, clk->ns_reg);
/*
* Switch to the new bank if clock is running. If it isn't, then
* no switch is necessary since we programmed the active bank.
*/
if (clk->enabled && clk->current_freq->freq_hz) {
ctl_reg_val ^= banks->bank_sel_mask;
writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
/*
* Wait at least 6 cycles of slowest bank's clock
* for the glitch-free MUX to fully switch sources.
*/
udelay(1);
/* Disable old bank's MN counter. */
ctl_reg_val &= ~(old_bank_masks->mnd_en_mask);
writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
/* Program old bank to a low-power source and divider. */
ns_reg_val &= ~(old_bank_masks->ns_mask);
ns_reg_val |= (clk->freq_tbl->ns_val & old_bank_masks->ns_mask);
writel_relaxed(ns_reg_val, clk->ns_reg);
}
/*
* If this freq requires the MN counter to be enabled,
* update the enable mask to match the current bank.
*/
if (nf->mnd_en_mask)
nf->mnd_en_mask = new_bank_masks->mnd_en_mask;
/* Update the NS mask to match the current bank. */
clk->ns_mask = new_bank_masks->ns_mask;
}
void set_rate_nop(struct rcg_clk *clk, struct clk_freq_tbl *nf)
{
/*
* Nothing to do for fixed-rate or integer-divider clocks. Any settings
* in NS registers are applied in the enable path, since power can be
* saved by leaving an un-clocked or slowly-clocked source selected
* until the clock is enabled.
*/
}

View File

@ -0,0 +1,193 @@
/*
* Copyright (c) 2012, 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 <Library/LKEnvLib.h>
#include <Chipset/clock.h>
#include "clock_p.h"
static struct clk_list msm_clk_list;
int clk_set_parent(struct clk *clk, struct clk *parent)
{
if (!clk->ops->set_parent)
return 0;
return clk->ops->set_parent(clk, parent);
}
struct clk *clk_get_parent(struct clk *clk)
{
if (!clk->ops->get_parent)
return NULL;
return clk->ops->get_parent(clk);
}
int clk_reset(struct clk *clk, enum clk_reset_action action)
{
if (!clk)
return 0;
if (!clk->ops->reset)
return 0;
return clk->ops->reset(clk, action);
}
/*
* Standard clock functions defined in include/clk.h
*/
int clk_enable(struct clk *clk)
{
int ret = 0;
struct clk *parent;
if (!clk)
return 0;
if (clk->count == 0) {
parent = clk_get_parent(clk);
ret = clk_enable(parent);
if (ret)
goto out;
if (clk->ops->enable)
ret = clk->ops->enable(clk);
if (ret) {
clk_disable(parent);
goto out;
}
}
clk->count++;
out:
return ret;
}
void clk_disable(struct clk *clk)
{
struct clk *parent;
if (!clk)
return;
if (clk->count == 0)
goto out;
if (clk->count == 1) {
if (clk->ops->disable)
clk->ops->disable(clk);
parent = clk_get_parent(clk);
clk_disable(parent);
}
clk->count--;
out:
return;
}
unsigned long clk_get_rate(struct clk *clk)
{
if (!clk->ops->get_rate)
return 0;
return clk->ops->get_rate(clk);
}
int clk_set_rate(struct clk *clk, unsigned long rate)
{
if (!clk->ops->set_rate)
return ERR_NOT_VALID;
return clk->ops->set_rate(clk, rate);
}
void clk_init(struct clk_lookup *clist, unsigned num)
{
if (clist && num) {
msm_clk_list.clist = (struct clk_lookup *)clist;
msm_clk_list.num = num;
}
}
struct clk *clk_get(const char *cid)
{
unsigned i;
struct clk_lookup *cl = msm_clk_list.clist;
unsigned num = msm_clk_list.num;
if (!cl || !num) {
dprintf(CRITICAL, "Alert!! clock list not defined!\n");
return NULL;
}
for (i = 0; i < num; i++, cl++) {
if (!strcmp(cl->con_id, cid)) {
return cl->clk;
}
}
dprintf(CRITICAL, "Alert!! Requested clock \"%s\" is not supported!\n", cid);
return NULL;
}
int clk_get_set_enable(char *id, unsigned long rate, bool enable)
{
int ret = NO_ERROR;
struct clk *cp;
/* Get clk */
cp = clk_get(id);
if (!cp) {
dprintf(CRITICAL, "Can't find clock with id: %s\n", id);
ret = ERR_NOT_VALID;
goto get_set_enable_error;
}
/* Set rate */
if (rate) {
ret = clk_set_rate(cp, rate);
if (ret) {
dprintf(CRITICAL, "Clock set rate failed.\n");
goto get_set_enable_error;
}
}
/* Enable clock */
if (enable) {
ret = clk_enable(cp);
if (ret) {
dprintf(CRITICAL, "Clock enable failed.\n");
}
}
get_set_enable_error:
return ret;
}
#ifdef DEBUG_CLOCK
struct clk_list *clk_get_list() { return &msm_clk_list; }
#endif

View File

@ -0,0 +1,277 @@
/*
* Copyright (c) 2012-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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 <Library/LKEnvLib.h>
#include <Chipset/clock.h>
// Must come in order
#include <Chipset/clock_lib2.h>
#include <Chipset/clock_pll.h>
#include "clock_p.h"
/*=============== CXO clock ops =============*/
int cxo_clk_enable(struct clk *clk)
{
/* Nothing to do. */
return 0;
}
void cxo_clk_disable(struct clk *clk)
{
/* Nothing to do. */
return;
}
/*=============== Branch clock ops =============*/
/* Branch clock enable */
int clock_lib2_branch_clk_enable(struct clk *clk)
{
int rc = 0;
uint32_t cbcr_val;
struct branch_clk *bclk = to_branch_clk(clk);
cbcr_val = readl(bclk->cbcr_reg);
cbcr_val |= CBCR_BRANCH_ENABLE_BIT;
writel(cbcr_val, bclk->cbcr_reg);
/* wait until status shows it is enabled */
while (readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT)
;
return rc;
}
/* Branch clock disable */
void clock_lib2_branch_clk_disable(struct clk *clk)
{
uint32_t cbcr_val;
struct branch_clk *bclk = to_branch_clk(clk);
cbcr_val = readl(bclk->cbcr_reg);
cbcr_val &= ~CBCR_BRANCH_ENABLE_BIT;
writel(cbcr_val, bclk->cbcr_reg);
/* wait until status shows it is disabled */
while (!(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT))
;
}
/* Branch clock set rate */
int clock_lib2_branch_set_rate(struct clk *c, unsigned rate)
{
struct branch_clk *branch = to_branch_clk(c);
if (!branch->has_sibling)
return clk_set_rate(branch->parent, rate);
return -1;
}
/*=============== Root clock ops =============*/
/* Root enable */
int clock_lib2_rcg_enable(struct clk *c)
{
/* Hardware feedback from branch enable results in root being enabled.
* Nothing to do here.
*/
return 0;
}
/* Root set rate:
* Find the entry in the frequecy table corresponding to the requested rate.
* Enable the source clock required for the new frequency.
* Call the set_rate function defined for this particular root clock.
*/
int clock_lib2_rcg_set_rate(struct clk *c, unsigned rate)
{
struct rcg_clk * rclk = to_rcg_clk(c);
struct clk_freq_tbl *nf; /* new freq */
int rc = 0;
/* ck if new freq is in table */
for (nf = rclk->freq_tbl; nf->freq_hz != FREQ_END && nf->freq_hz != rate;
nf++)
;
/* Frequency not found in the table */
if (nf->freq_hz == FREQ_END)
return ERR_INVALID_ARGS;
/* Check if frequency is actually changed. */
if (nf == rclk->current_freq)
return rc;
/* First enable the source clock for this freq. */
clk_enable(nf->src_clk);
/* Perform clock-specific frequency switch operations. */
ASSERT(rclk->set_rate);
rclk->set_rate(rclk, nf);
/* update current freq */
rclk->current_freq = nf;
return rc;
}
/* root update config: informs h/w to start using the new config values */
static void clock_lib2_rcg_update_config(struct rcg_clk *rclk)
{
uint32_t cmd;
cmd = readl(rclk->cmd_reg);
cmd |= CMD_UPDATE_BIT;
writel(cmd, rclk->cmd_reg);
/* Wait for frequency to be updated. */
while (readl(rclk->cmd_reg) & CMD_UPDATE_MASK)
;
}
/* root set rate for clocks with half integer and MND divider */
void clock_lib2_rcg_set_rate_mnd(
struct rcg_clk *rclk, struct clk_freq_tbl *freq)
{
uint32_t cfg;
/* Program MND values */
writel(freq->m_val, rclk->m_reg);
writel(freq->n_val, rclk->n_reg);
writel(freq->d_val, rclk->d_reg);
/* setup src select and divider */
cfg = readl(rclk->cfg_reg);
cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK | CFG_MODE_MASK);
cfg |= freq->div_src_val;
if (freq->n_val != 0) {
cfg |= (CFG_MODE_DUAL_EDGE << CFG_MODE_OFFSET);
}
writel(cfg, rclk->cfg_reg);
/* Inform h/w to start using the new config. */
clock_lib2_rcg_update_config(rclk);
}
/* root set rate for clocks with half integer divider */
void clock_lib2_rcg_set_rate_hid(
struct rcg_clk *rclk, struct clk_freq_tbl *freq)
{
uint32_t cfg;
/* setup src select and divider */
cfg = readl(rclk->cfg_reg);
cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK);
cfg |= freq->div_src_val;
writel(cfg, rclk->cfg_reg);
clock_lib2_rcg_update_config(rclk);
}
/*=============== Vote clock ops =============*/
/* Vote clock enable */
int clock_lib2_vote_clk_enable(struct clk *c)
{
uint32_t vote_regval;
uint32_t val;
struct vote_clk *vclk = to_local_vote_clk(c);
vote_regval = readl(vclk->vote_reg);
vote_regval |= vclk->en_mask;
writel_relaxed(vote_regval, vclk->vote_reg);
do {
val = readl(vclk->cbcr_reg);
val &= BRANCH_CHECK_MASK;
}
/* wait until status shows it is enabled */
while ((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL));
return 0;
}
/* Vote clock disable */
void clock_lib2_vote_clk_disable(struct clk *c)
{
uint32_t vote_regval;
struct vote_clk *vclk = to_local_vote_clk(c);
vote_regval = readl(vclk->vote_reg);
vote_regval &= ~vclk->en_mask;
writel_relaxed(vote_regval, vclk->vote_reg);
}
/* Reset clock */
static int
__clock_lib2_branch_clk_reset(uint32_t bcr_reg, enum clk_reset_action action)
{
uint32_t reg;
int ret = 0;
reg = readl(bcr_reg);
switch (action) {
case CLK_RESET_ASSERT:
reg |= BIT(0);
break;
case CLK_RESET_DEASSERT:
reg &= ~BIT(0);
break;
default:
ret = 1;
}
writel(reg, bcr_reg);
/* Wait for writes to go through */
dmb();
return ret;
}
int clock_lib2_reset_clk_reset(struct clk *c, enum clk_reset_action action)
{
struct reset_clk *rst = to_reset_clk(c);
if (!rst)
return 0;
return __clock_lib2_branch_clk_reset(rst->bcr_reg, action);
}
int clock_lib2_branch_clk_reset(struct clk *c, enum clk_reset_action action)
{
struct branch_clk *bclk = to_branch_clk(c);
if (!bclk)
return 0;
return __clock_lib2_branch_clk_reset((uint32_t)bclk->bcr_reg, action);
}

View File

@ -0,0 +1,110 @@
#ifndef _CLOCK_PRIVATE_H
#define _CLOCK_PRIVATE_H
/**
* clk_get - lookup and obtain a reference to a clock producer.
* @dev: device for clock "consumer"
* @id: clock comsumer ID
*
* Returns a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
*
* Drivers must assume that the clock source is not enabled.
*
* clk_get should not be called from within interrupt context.
*/
struct clk *clk_get(const char *id);
/**
* clk_enable - inform the system when the clock source should be running.
* @clk: clock source
*
* If the clock can not be enabled/disabled, this should return success.
*
* Returns success (0) or negative errno.
*/
int clk_enable(struct clk *clk);
/**
* clk_disable - inform the system when the clock source is no longer required.
* @clk: clock source
*
* Inform the system that a clock source is no longer required by
* a driver and may be shut down.
*
* Implementation detail: if the clock source is shared between
* multiple drivers, clk_enable() calls must be balanced by the
* same number of clk_disable() calls for the clock source to be
* disabled.
*/
void clk_disable(struct clk *clk);
/**
* clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
* This is only valid once the clock source has been enabled.
* @clk: clock source
*/
unsigned long clk_get_rate(struct clk *clk);
/**
* clk_set_rate - set the clock rate for a clock source
* @clk: clock source
* @rate: desired clock rate in Hz
*
* Returns success (0) or negative errno.
*/
int clk_set_rate(struct clk *clk, unsigned long rate);
/**
* clk_set_parent - set the parent clock source for this clock
* @clk: clock source
* @parent: parent clock source
*
* Returns success (0) or negative errno.
*/
int clk_set_parent(struct clk *clk, struct clk *parent);
/**
* clk_get_parent - get the parent clock source for this clock
* @clk: clock source
*
* Returns struct clk corresponding to parent clock source, or
* valid IS_ERR() condition containing errno.
*/
struct clk *clk_get_parent(struct clk *clk);
/**
* clk_get_set_enable -
* -- get the clock.
* -- set the rate to @rate if @rate is non-zero
* -- enable the clock if @enable = ture;
* @id: clock identifier (char *)
* @rate: desired clock rate in Hz
*
* Returns success (0) or negative errno.
*/
int clk_get_set_enable(char *id, unsigned long rate, bool enable);
#ifdef DEBUG_CLOCK
struct clk_list *clk_get_list(void);
#endif
/**
* clk_init - register all the clocks in the system.
* @clist: pointer to clock list
* @num: number of clocks in the list
*/
void clk_init(struct clk_lookup *clist, unsigned num);
/**
* clk_reset - Reset block using BCR
* @clk: pointer to clock
* @action: clock assert or deassert
*/
int clk_reset(struct clk *clk, enum clk_reset_action);
#endif // _CLOCK_PRIVATE_H

View File

@ -0,0 +1,139 @@
/*
* 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 <Library/LKEnvLib.h>
#include <Chipset/clock.h>
// Must come in order
#include <Chipset/clock_pll.h>
/*
* pll_vote_clk functions
*/
int pll_vote_clk_enable(struct clk *clk)
{
uint32_t ena;
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
ena = readl_relaxed(pll->en_reg);
ena |= pll->en_mask;
writel_relaxed(ena, pll->en_reg);
/* Wait until PLL is enabled */
while ((readl_relaxed(pll->status_reg) & pll->status_mask) == 0)
;
return 0;
}
void pll_vote_clk_disable(struct clk *clk)
{
uint32_t ena;
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
ena = readl_relaxed(pll->en_reg);
ena &= ~(pll->en_mask);
writel_relaxed(ena, pll->en_reg);
}
unsigned pll_vote_clk_get_rate(struct clk *clk)
{
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
return pll->rate;
}
struct clk *pll_vote_clk_get_parent(struct clk *clk)
{
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
return pll->parent;
}
int pll_vote_clk_is_enabled(struct clk *clk)
{
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
return !!(readl_relaxed(pll->status_reg) & pll->status_mask);
}
/*
* PLLs functions
*/
int pll_clk_enable(struct clk *clk)
{
uint32_t mode;
struct pll_clk *pll = to_pll_clk(clk);
mode = readl_relaxed(pll->mode_reg);
/* Disable PLL bypass mode. */
mode |= BIT(1);
writel_relaxed(mode, pll->mode_reg);
/*
* H/W requires a 5us delay between disabling the bypass and
* de-asserting the reset. Delay 10us just to be safe.
*/
udelay(10);
/* De-assert active-low PLL reset. */
mode |= BIT(2);
writel_relaxed(mode, pll->mode_reg);
/* Wait until PLL is locked. */
udelay(50);
/* Enable PLL output. */
mode |= BIT(0);
writel_relaxed(mode, pll->mode_reg);
return 0;
}
void pll_clk_disable(struct clk *clk)
{
uint32_t mode;
struct pll_clk *pll = to_pll_clk(clk);
/*
* Disable the PLL output, disable test mode, enable
* the bypass mode, and assert the reset.
*/
mode = readl_relaxed(pll->mode_reg);
mode &= ~BM(3, 0);
writel_relaxed(mode, pll->mode_reg);
}
unsigned pll_clk_get_rate(struct clk *clk)
{
struct pll_clk *pll = to_pll_clk(clk);
return pll->rate;
}
struct clk *pll_clk_get_parent(struct clk *clk)
{
struct pll_clk *pll = to_pll_clk(clk);
return pll->parent;
}

View File

@ -0,0 +1,235 @@
/*
* 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 CLOCK_LOCAL_H
#define CLOCK_LOCAL_H
struct clk;
struct clk_ops;
#define FREQ_END (UINT32_MAX - 1)
#define F_END \
{ \
.freq_hz = FREQ_END, \
}
#define container_of(ptr, type, member) \
((type *)((addr_t)(ptr)-offsetof(type, member)))
/*
* Bit manipulation macros
*/
#define BM(msb, lsb) \
(((((uint32_t)-1) << (31 - msb)) >> (31 - msb + lsb)) << lsb)
#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb))
/*
* Halt/Status Checking Mode Macros
*/
#define HALT 0 /* Bit pol: 1 = halted */
#define NOCHECK 1 /* No bit to check, do nothing */
#define HALT_VOTED 2 /* Bit pol: 1 = halted; delay on disable */
#define ENABLE 3 /* Bit pol: 1 = running */
#define ENABLE_VOTED 4 /* Bit pol: 1 = running; delay on disable */
#define DELAY 5 /* No bit to check, just delay */
/*
* Variables from clock-local driver
*/
extern struct fixed_clk gnd_clk;
/*
* Generic frequency-definition structs and macros
*/
struct clk_freq_tbl {
const uint32_t freq_hz;
struct clk * src_clk;
const uint32_t md_val;
const uint32_t ns_val;
const uint32_t ctl_val;
uint32_t mnd_en_mask;
void *const extra_freq_data;
};
extern struct clk_freq_tbl local_dummy_freq;
/* Some clocks have two banks to avoid glitches when switching frequencies.
* The unused bank is programmed while running on the other bank, and
* switched to afterwards. The following two structs describe the banks. */
struct bank_mask_info {
void *const md_reg;
const uint32_t ns_mask;
const uint32_t rst_mask;
const uint32_t mnd_en_mask;
const uint32_t mode_mask;
};
struct bank_masks {
const uint32_t bank_sel_mask;
const struct bank_mask_info bank0_mask;
const struct bank_mask_info bank1_mask;
};
/**
* struct branch - branch on/off
* @ctl_reg: clock control register
* @en_mask: ORed with @ctl_reg to enable the clock
* @halt_reg: halt register
* @halt_check: type of halt check to perform
* @halt_bit: ANDed with @halt_reg to test for clock halted
* @reset_reg: reset register
* @reset_mask: ORed with @reset_reg to reset the clock domain
*/
struct branch {
void *const ctl_reg;
const uint32_t en_mask;
void *const halt_reg;
const uint16_t halt_check;
const uint16_t halt_bit;
void *const reset_reg;
const uint32_t reset_mask;
};
/*
* Generic clock-definition struct and macros
*/
struct rcg_clk {
bool enabled;
void *const ns_reg;
void *const md_reg;
const uint32_t root_en_mask;
uint32_t ns_mask;
const uint32_t ctl_mask;
struct bank_masks *const bank_masks;
void (*set_rate)(struct rcg_clk *, struct clk_freq_tbl *);
struct clk_freq_tbl *freq_tbl;
struct clk_freq_tbl *current_freq;
struct clk * depends;
struct branch b;
struct clk c;
};
static inline struct rcg_clk *to_rcg_clk(struct clk *clk)
{
return container_of(clk, struct rcg_clk, c);
}
/**
* struct fixed_clk - fixed rate clock (used for crystal oscillators)
* @rate: output rate
* @c: clk
*/
struct fixed_clk {
unsigned long rate;
struct clk c;
};
static inline struct fixed_clk *to_fixed_clk(struct clk *clk)
{
return container_of(clk, struct fixed_clk, c);
}
static inline unsigned fixed_clk_get_rate(struct clk *clk)
{
struct fixed_clk *f = to_fixed_clk(clk);
return f->rate;
}
/**
* struct branch_clk - branch
* @enabled: true if clock is on, false otherwise
* @b: branch
* @parent: clock source
* @c: clk
*
* An on/off switch with a rate derived from the parent.
*/
struct branch_clk {
bool enabled;
struct branch b;
struct clk * parent;
struct clk c;
};
static inline struct branch_clk *to_branch_clk(struct clk *clk)
{
return container_of(clk, struct branch_clk, c);
}
int branch_clk_enable(struct clk *clk);
void branch_clk_disable(struct clk *clk);
struct clk *branch_clk_get_parent(struct clk *clk);
int branch_clk_set_parent(struct clk *clk, struct clk *parent);
int branch_clk_is_enabled(struct clk *clk);
void branch_clk_auto_off(struct clk *clk);
int branch_clk_reset(struct clk *c, enum clk_reset_action action);
/**
* struct measure_clk - for rate measurement debug use
* @sample_ticks: sample period in reference clock ticks
* @multiplier: measurement scale-up factor
* @divider: measurement scale-down factor
* @c: clk
*/
struct measure_clk {
uint64_t sample_ticks;
uint32_t multiplier;
uint32_t divider;
struct clk c;
};
extern struct clk_ops clk_ops_measure;
static inline struct measure_clk *to_measure_clk(struct clk *clk)
{
return container_of(clk, struct measure_clk, c);
}
/*
* clk_ops APIs
*/
int local_clk_enable(struct clk *c);
void local_clk_disable(struct clk *c);
int local_clk_set_rate(struct clk *c, unsigned rate);
unsigned local_clk_get_rate(struct clk *c);
int local_clk_is_enabled(struct clk *clk);
long local_clk_round_rate(struct clk *c, unsigned rate);
struct clk *local_clk_get_parent(struct clk *clk);
/*
* Generic set-rate implementations
*/
void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf);
void set_rate_mnd_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf);
void set_rate_nop(struct rcg_clk *clk, struct clk_freq_tbl *nf);
#endif

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2012, 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 CLOCK_H
#define CLOCK_H
enum clk_reset_action { CLK_RESET_DEASSERT = 0, CLK_RESET_ASSERT = 1 };
struct clk;
struct clk_ops {
int (*enable)(struct clk *clk);
void (*disable)(struct clk *clk);
void (*auto_off)(struct clk *clk);
int (*reset)(struct clk *clk, enum clk_reset_action action);
int (*set_rate)(struct clk *clk, unsigned rate);
int (*set_min_rate)(struct clk *clk, unsigned rate);
int (*set_max_rate)(struct clk *clk, unsigned rate);
int (*set_flags)(struct clk *clk, unsigned flags);
unsigned (*get_rate)(struct clk *clk);
int (*list_rate)(struct clk *clk, unsigned n);
int (*is_enabled)(struct clk *clk);
long (*round_rate)(struct clk *clk, unsigned rate);
int (*set_parent)(struct clk *clk, struct clk *parent);
struct clk *(*get_parent)(struct clk *clk);
bool (*is_local)(struct clk *clk);
};
/**
* struct clk
* @count: enable refcount
* @lock: protects clk_enable()/clk_disable() path and @count
*/
struct clk {
uint32_t flags;
uint32_t rate;
struct clk_ops *ops;
const char * dbg_name;
unsigned count;
};
struct clk_lookup {
const char *con_id;
struct clk *clk;
};
struct clk_list {
struct clk_lookup *clist;
unsigned num;
};
#define CLK_LOOKUP(con, c) \
{ \
.con_id = con, .clk = &c \
}
#endif

View File

@ -0,0 +1,223 @@
/*
* Copyright (c) 2012-2014, 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 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 __CLOCK_LIB2_H
#define __CLOCK_LIB2_H
/*
* Bit manipulation macros
*/
#define BM(msb, lsb) \
(((((uint32_t)-1) << (31 - msb)) >> (31 - msb + lsb)) << lsb)
#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb))
#define container_of(ptr, type, member) \
((type *)((addr_t)(ptr)-offsetof(type, member)))
/* Frequency Macros */
#define FREQ_END (UINT32_MAX - 1)
#define F_END \
{ \
.freq_hz = FREQ_END, \
}
/* F(frequency, source, div, m, n) */
#define F(f, s, div, m, n) \
{ \
.freq_hz = (f), .src_clk = &s##_clk_src.c, .m_val = (m), \
.n_val = ~((n) - (m)) * !!(n), .d_val = ~(n), \
.div_src_val = \
BVAL(4, 0, (int)(2 * (div)-1)) | BVAL(10, 8, s##_source_val), \
}
/* F(frequency, source, div, m, n) */
#define F_EXT_SRC(f, s, div, m, n) \
{ \
.freq_hz = (f), .m_val = (m), .n_val = ~((n) - (m)) * !!(n), \
.d_val = ~(n), \
.div_src_val = \
BVAL(4, 0, (int)(2 * (div)-1)) | BVAL(10, 8, s##_source_val), \
}
/* F_MM(frequency, source, div, m, n) */
#define F_MM(f, s, div, m, n) \
{ \
.freq_hz = (f), .src_clk = &s##_clk_src.c, .m_val = (m), \
.n_val = ~((n) - (m)) * !!(n), .d_val = ~(n), \
.div_src_val = \
BVAL(4, 0, (int)(2 * (div)-1)) | BVAL(10, 8, s##_mm_source_val), \
}
#define F_MDSS(f, s, div, m, n) \
{ \
.freq_hz = (f), .m_val = (m), .n_val = ~((n) - (m)) * !!(n), \
.d_val = ~(n), \
.div_src_val = \
BVAL(4, 0, (int)(2 * (div)-1)) | BVAL(10, 8, s##_mm_source_val), \
}
/* Branch Clock Bits */
#define CBCR_BRANCH_ENABLE_BIT BIT(0)
#define CBCR_BRANCH_OFF_BIT BIT(31)
#define BRANCH_CHECK_MASK BM(31, 28)
#define BRANCH_ON_VAL BVAL(31, 28, 0x0)
#define BRANCH_NOC_FSM_ON_VAL BVAL(31, 28, 0x2)
/* Root Clock Bits */
#define CMD_UPDATE_BIT BIT(0)
#define CMD_UPDATE_MASK 1
#define CFG_SRC_DIV_OFFSET 0
#define CFG_SRC_DIV_MASK (0x1F << CFG_SRC_DIV_OFFSET)
#define CFG_SRC_SEL_OFFSET 8
#define CFG_SRC_SEL_MASK (0x3 << CFG_SRC_SEL_OFFSET)
#define CFG_MODE_DUAL_EDGE 0x2
#define CFG_MODE_OFFSET 12
#define CFG_MODE_MASK (0x3 << CFG_MODE_OFFSET)
/*
* Generic frequency-definition structs and macros
*/
struct clk_freq_tbl {
const uint32_t freq_hz;
struct clk * src_clk;
const uint32_t div_src_val;
/* TODO: find out if sys_vdd is needed. */
const uint32_t m_val;
const uint32_t n_val; /* not_n_minus_m_val */
const uint32_t d_val; /* not_2d_val */
};
/* Fixed clock */
struct fixed_clk {
struct clk c;
};
/* Branch clock */
struct branch_clk {
uint32_t *const bcr_reg;
uint32_t *const cbcr_reg;
void (*set_rate)(struct branch_clk *, struct clk_freq_tbl *);
struct clk *parent;
struct clk c;
int has_sibling;
uint32_t cur_div;
uint32_t max_div;
uint32_t halt_check;
};
/* Root Clock */
struct rcg_clk {
/* RCG registers for this clock */
uint32_t *const cmd_reg; /* Command reg */
uint32_t *const cfg_reg; /* Config reg */
uint32_t *const m_reg; /* m */
uint32_t *const n_reg; /* not (n-m) */
uint32_t *const d_reg; /* not (2d) */
/* set rate function for this clock */
void (*set_rate)(struct rcg_clk *, struct clk_freq_tbl *);
/* freq table */
struct clk_freq_tbl *freq_tbl;
struct clk_freq_tbl *current_freq;
struct clk c;
};
/* Vote Clock */
struct vote_clk {
uint32_t *const cbcr_reg;
uint32_t *const vote_reg;
uint32_t en_mask;
struct clk c;
};
struct reset_clk {
uint32_t bcr_reg;
struct clk c;
};
static inline struct reset_clk *to_reset_clk(struct clk *clk)
{
return container_of(clk, struct reset_clk, c);
}
static inline struct rcg_clk *to_rcg_clk(struct clk *clk)
{
return container_of(clk, struct rcg_clk, c);
}
static inline struct branch_clk *to_branch_clk(struct clk *clk)
{
return container_of(clk, struct branch_clk, c);
}
static inline struct vote_clk *to_local_vote_clk(struct clk *clk)
{
return container_of(clk, struct vote_clk, c);
}
/* RCG clock functions */
int clock_lib2_rcg_enable(struct clk *c);
int clock_lib2_rcg_set_rate(struct clk *c, unsigned rate);
void clock_lib2_rcg_set_rate_mnd(
struct rcg_clk *rclk, struct clk_freq_tbl *freq);
void clock_lib2_rcg_set_rate_hid(
struct rcg_clk *rclk, struct clk_freq_tbl *freq);
/* CXO clock functions */
int cxo_clk_enable(struct clk *clk);
void cxo_clk_disable(struct clk *clk);
/* Branch clock functions */
int clock_lib2_branch_clk_enable(struct clk *clk);
void clock_lib2_branch_clk_disable(struct clk *clk);
int clock_lib2_branch_set_rate(struct clk *c, unsigned rate);
/* Vote clock functions*/
int clock_lib2_vote_clk_enable(struct clk *c);
void clock_lib2_vote_clk_disable(struct clk *c);
/* clock reset function */
int clock_lib2_reset_clk_reset(struct clk *c, enum clk_reset_action action);
int clock_lib2_branch_clk_reset(struct clk *c, enum clk_reset_action action);
#endif

View File

@ -0,0 +1,102 @@
/*
* 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 CLOCK_PLL_H
#define CLOCK_PLL_H
/*
* Bit manipulation macros
*/
#define BM(msb, lsb) \
(((((uint32_t)-1) << (31 - msb)) >> (31 - msb + lsb)) << lsb)
#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb))
struct clk;
struct clk_ops;
#define container_of(ptr, type, member) \
((type *)((addr_t)(ptr)-offsetof(type, member)))
/**
* struct pll_vote_clk - phase locked loop (HW voteable)
* @rate: output rate
* @en_reg: enable register
* @en_mask: ORed with @en_reg to enable the clock
* @status_reg: status register
* @parent: clock source
* @c: clk
*/
struct pll_vote_clk {
unsigned long rate;
void *const en_reg;
const uint32_t en_mask;
void *const status_reg;
const uint32_t status_mask;
struct clk *parent;
struct clk c;
};
static inline struct pll_vote_clk *to_pll_vote_clk(struct clk *clk)
{
return container_of(clk, struct pll_vote_clk, c);
}
/**
* struct pll_clk - phase locked loop
* @rate: output rate
* @mode_reg: enable register
* @parent: clock source
* @c: clk
*/
struct pll_clk {
unsigned long rate;
void *const mode_reg;
struct clk *parent;
struct clk c;
};
static inline struct pll_clk *to_pll_clk(struct clk *clk)
{
return container_of(clk, struct pll_clk, c);
}
int pll_vote_clk_enable(struct clk *clk);
void pll_vote_clk_disable(struct clk *clk);
unsigned pll_vote_clk_get_rate(struct clk *clk);
struct clk *pll_vote_clk_get_parent(struct clk *clk);
int pll_vote_clk_is_enabled(struct clk *clk);
int pll_clk_enable(struct clk *clk);
void pll_clk_disable(struct clk *clk);
unsigned pll_clk_get_rate(struct clk *clk);
struct clk *pll_clk_get_parent(struct clk *clk);
#endif

View File

@ -0,0 +1,111 @@
#ifndef __LIBRARY_LKENV_H__
#define __LIBRARY_LKENV_H__
#include <Library/ArmLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/PrintLib.h>
#include <Library/TimerLib.h>
#include "minstdbool.h"
#include "minstdint.h"
#define REG32(addr) ((volatile uint32_t *)(addr))
#define writel_rt(v, a) (*REG32(a) = (v))
#define readl_rt(a) (*REG32(a))
#define writel(v, a) MmioWrite32((UINTN)(a), (UINT32)(v))
#define readl(a) MmioRead32((UINTN)(a))
#define writeb(v, a) MmioWrite8((UINTN)(a), (UINT8)(v))
#define readb(a) MmioRead8((UINTN)(a))
#define writehw(v, a) MmioWrite16((UINTN)(a), (UINT16)(v))
#define readhw(a) MmioRead16((UINTN)(a))
#define RMWREG32(addr, startbit, width, val) \
writel( \
(readl(addr) & ~(((1 << (width)) - 1) << (startbit))) | \
((val) << (startbit)), \
addr)
#define BIT(bit) (1 << (bit))
#ifdef MSM_SECURE_IO
#define readl_relaxed secure_readl
#define writel_relaxed secure_writel
#else
#define readl_relaxed readl
#define writel_relaxed writel
#endif
#define NO_ERROR 0
#define ERROR -1
#define ERR_NOT_FOUND -2
#define ERR_NO_MEMORY -5
#define ERR_NOT_VALID -7
#define ERR_INVALID_ARGS -8
#define ERR_IO -20
#define ERR_NOT_SUPPORTED -24
#include "minstdbool.h"
#include "minstring.h"
#define va_list VA_LIST
#define offsetof(type, member) OFFSET_OF(type, member)
#define __PACKED __attribute__((packed))
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
#define ROUNDDOWN(a, b) ((a) & ~((b)-1))
#define CACHE_LINE (ArmDataCacheLineLength())
#define IS_CACHE_LINE_ALIGNED(addr) !((UINTN)(addr) & (CACHE_LINE - 1))
#define snprintf(s, n, fmt, ...) \
((int)AsciiSPrint((s), (n), (fmt), ##__VA_ARGS__))
/* debug levels */
#define CRITICAL DEBUG_ERROR
#define ALWAYS DEBUG_ERROR
#define INFO DEBUG_INFO
#define SPEW DEBUG_VERBOSE
#if !defined(MDEPKG_NDEBUG)
#define dprintf(level, fmt, ...) \
do { \
if (DebugPrintEnabled()) { \
CHAR8 __printbuf[100]; \
UINTN __printindex; \
CONST CHAR8 *__fmtptr = (fmt); \
UINTN __fmtlen = AsciiStrSize(__fmtptr); \
CopyMem(__printbuf, __fmtptr, __fmtlen); \
__printbuf[__fmtlen - 1] = 0; \
for (__printindex = 1; __printbuf[__printindex]; __printindex++) { \
if (__printbuf[__printindex - 1] == '%' && \
__printbuf[__printindex] == 's') \
__printbuf[__printindex] = 'a'; \
} \
DEBUG(((level), __printbuf, ##__VA_ARGS__)); \
} \
} while (0)
#else
#define dprintf(level, fmt, ...)
#endif
#define ntohl(n) SwapBytes32(n)
#define dmb() ArmDataMemoryBarrier()
#define dsb() ArmDataSynchronizationBarrier()
#define mdelay(msecs) MicroSecondDelay((msecs)*1000)
#define udelay(usecs) MicroSecondDelay((usecs))
#define arch_clean_invalidate_cache_range(start, len) \
WriteBackInvalidateDataCacheRange((VOID *)(UINTN)(start), (UINTN)(len))
#define arch_invalidate_cache_range(start, len) \
InvalidateDataCacheRange((VOID *)(UINTN)(start), (UINTN)(len));
#define __ALWAYS_INLINE __attribute__((always_inline))
#define ROUND_TO_PAGE(x) (x & (~(EFI_PAGE_SIZE - 1)))
#endif

View File

@ -0,0 +1,12 @@
#ifndef __LIBRARY_QCOM_CLOCK_LIB_H__
#define __LIBRARY_QCOM_CLOCK_LIB_H__
#include <Protocol/QcomClock.h>
RETURN_STATUS
EFIAPI
ClockImplLibInitialize(VOID);
extern QCOM_CLOCK_PROTOCOL *gClock;
#endif

View File

@ -0,0 +1,11 @@
#ifndef __LIBRARY_QCOM_PLATFORM_CLOCKINIT_LIB_H__
#define __LIBRARY_QCOM_PLATFORM_CLOCKINIT_LIB_H__
#include <Chipset/clock.h>
#include <Library/LKEnvLib.h>
EFI_STATUS
EFIAPI
LibQcomPlatformClockInit(struct clk_lookup **clist, unsigned *num);
#endif

View File

@ -0,0 +1,11 @@
#ifndef __MIN_STDBOOL_H__
#define __MIN_STDBOOL_H__
#include <Library/BaseLib.h>
typedef BOOLEAN bool;
#define true TRUE
#define false FALSE
#endif

View File

@ -0,0 +1,70 @@
#ifndef __MIN_STDINT_H__
#define __MIN_STDINT_H__
#include <Library/BaseLib.h>
typedef UINTN size_t;
typedef INT8 int8_t;
typedef INT16 int16_t;
typedef INT32 int32_t;
typedef INT64 int64_t;
typedef UINT8 uint8_t;
typedef UINT16 uint16_t;
typedef UINT32 uint32_t;
typedef UINT64 uint64_t;
typedef UINTN addr_t;
typedef UINTN paddr_t;
typedef UINT8 u8;
typedef UINT16 u16;
typedef UINT32 u32;
typedef UINT64 u64;
#ifndef INT16_MIN
#define INT16_MIN MIN_INT16
#endif
#ifndef INT16_MAX
#define INT16_MAX MAX_INT16
#endif
#ifndef UINT16_MIN
#define UINT16_MIN MIN_UINT16
#endif
#ifndef UINT16_MAX
#define UINT16_MAX MAX_UINT16
#endif
#ifndef INT32_MIN
#define INT32_MIN MIN_INT32
#endif
#ifndef INT32_MAX
#define INT32_MAX MAX_INT32
#endif
#ifndef UINT32_MIN
#define UINT32_MIN MIN_UINT32
#endif
#ifndef UINT32_MAX
#define UINT32_MAX MAX_UINT32
#endif
#ifndef UINT_MAX
#define UINT_MAX MAX_UINTN
#endif
#ifndef ULONG_MAX
#define ULONG_MAX (~0UL)
#endif
#ifndef LONG_MAX
#define LONG_MAX ((long)(~0UL >> 1))
#endif
#endif

View File

@ -0,0 +1,17 @@
#ifndef __MIN_STRING_H__
#define __MIN_STRING_H__
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#define strcmp(s1, s2) ((int)AsciiStrCmp((s1), (s2)))
#define strncmp(s1, s2, n) ((int)AsciiStrnCmp((s1), (s2), (n)))
#define strlen(s) ((size_t)AsciiStrLen((s)))
#define strlcpy(dst, src, n) AsciiStrCpyS((dst), (n), (src))
#define strstr(s1, s2) AsciiStrStr((s1), (s2))
#define memset(s, c, n) SetMem((s), (UINTN)(n), (UINT8)(c))
#define memcpy(s1, s2, n) CopyMem((s1), (s2), (n))
#define memmove(s1, s2, n) CopyMem((s1), (s2), (n))
#define memcmp(s1, s2, n) ((int)CompareMem((s1), (s2), (n)))
#endif

View File

@ -0,0 +1,93 @@
/* Copyright (c) 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.
*/
#ifndef __MSM8916_CLOCK_H
#define __MSM8916_CLOCK_H
#include <Chipset/clock.h>
#include <Chipset/clock_lib2.h>
#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
#define REG_MM(off) (CLK_CTL_BASE + (off))
#define MDP_GDSCR REG_MM(0x4D078)
#define GDSC_POWER_ON_BIT BIT(31)
#define GDSC_POWER_ON_STATUS_BIT BIT(29)
#define GDSC_EN_FEW_WAIT_MASK (0x0F << 16)
#define GDSC_EN_FEW_WAIT_256_MASK BIT(19)
#define VSYNC_CMD_RCGR REG_MM(0x4D02C)
#define VSYNC_CFG_RCGR REG_MM(0x4D030)
#define MDSS_VSYNC_CBCR REG_MM(0x4D090)
#define MDP_CMD_RCGR REG_MM(0x4D014)
#define MDP_CFG_RCGR REG_MM(0x4D018)
#define MDP_CBCR REG_MM(0x4D088)
#define MDP_AHB_CBCR REG_MM(0x4D07C)
#define MDP_AXI_CBCR REG_MM(0x4D080)
#define DSI_BYTE0_CMD_RCGR REG_MM(0x4D044)
#define DSI_BYTE0_CFG_RCGR REG_MM(0x4D048)
#define DSI_BYTE0_CBCR REG_MM(0x4D094)
#define DSI_ESC0_CMD_RCGR REG_MM(0x4D05C)
#define DSI_ESC0_CFG_RCGR REG_MM(0x4D060)
#define DSI_ESC0_CBCR REG_MM(0x4D098)
#define DSI_PIXEL0_CMD_RCGR REG_MM(0x4D000)
#define DSI_PIXEL0_CFG_RCGR REG_MM(0x4D004)
#define DSI_PIXEL0_CBCR REG_MM(0x4D084)
#define DSI_PIXEL0_M REG_MM(0x4D008)
#define DSI_PIXEL0_N REG_MM(0x4D00C)
#define DSI_PIXEL0_D REG_MM(0x4D010)
#define DSI_BYTE1_CMD_RCGR REG_MM(0x4D0B0)
#define DSI_BYTE1_CFG_RCGR REG_MM(0x4D0B4)
#define DSI_BYTE1_CBCR REG_MM(0x4D0A0)
#define DSI_ESC1_CMD_RCGR REG_MM(0x4D0A8)
#define DSI_ESC1_CFG_RCGR REG_MM(0x4D0AC)
#define DSI_ESC1_CBCR REG_MM(0x4D09C)
#define DSI_PIXEL1_CMD_RCGR REG_MM(0x4D0B8)
#define DSI_PIXEL1_CFG_RCGR REG_MM(0x4D0BC)
#define DSI_PIXEL1_CBCR REG_MM(0x4D0A4)
#define DSI_PIXEL1_M REG_MM(0x4D0C0)
#define DSI_PIXEL1_N REG_MM(0x4D0C4)
#define DSI_PIXEL1_D REG_MM(0x4D0C8)
void platform_clock_init(void);
void clock_init_mmc(uint32_t interface);
void clock_config_mmc(uint32_t interface, uint32_t freq);
void clock_config_uart_dm(uint8_t id);
void hsusb_clock_init(void);
void clock_config_ce(uint8_t instance);
void mdp_clock_init(void);
void mdp_gdsc_ctrl(uint8_t enable);
void clock_ce_enable(uint8_t instance);
void clock_ce_disable(uint8_t instance);
void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);
#endif

View File

@ -0,0 +1,286 @@
/* 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 _PLATFORM_MSM8916_IOMAP_H_
#define _PLATFORM_MSM8916_IOMAP_H_
#define MSM_IOMAP_BASE 0x00000000
#define MSM_IOMAP_END 0x08000000
#define A53_SS_BASE 0x0B000000
#define A53_SS_END 0x0B200000
#define SYSTEM_IMEM_BASE 0x08600000
#define MSM_SHARED_IMEM_BASE 0x08600000
#define RESTART_REASON_ADDR (MSM_SHARED_IMEM_BASE + 0x65C)
#define BS_INFO_OFFSET (0x6B0)
#define BS_INFO_ADDR (MSM_SHARED_IMEM_BASE + BS_INFO_OFFSET)
#define SDRAM_START_ADDR 0x80000000
#define MSM_SHARED_BASE 0x86300000
#define APPS_SS_BASE 0x0B000000
#define DDR_START get_ddr_start()
#define ABOOT_FORCE_KERNEL_ADDR DDR_START + 0x8000
#define ABOOT_FORCE_KERNEL64_ADDR DDR_START + 0x80000
#define ABOOT_FORCE_RAMDISK_ADDR DDR_START + 0x2000000
#define ABOOT_FORCE_TAGS_ADDR DDR_START + 0x1E00000
#define MSM_GIC_DIST_BASE APPS_SS_BASE
#define MSM_GIC_CPU_BASE (APPS_SS_BASE + 0x2000)
#define MSM_WATCHDOG_BASE (APPS_SS_BASE + 0x00017000)
#define MSM_WATCHDOG_RST (MSM_WATCHDOG_BASE + 0x04)
#define MSM_WATCHDOG_EN (MSM_WATCHDOG_BASE + 0x08)
#define APPS_APCS_QTMR_AC_BASE (APPS_SS_BASE + 0x00020000)
#define APPS_APCS_F0_QTMR_V1_BASE (APPS_SS_BASE + 0x00021000)
#define QTMR_BASE APPS_APCS_F0_QTMR_V1_BASE
#define APCS_BANKED_SAW2_BASE (APPS_SS_BASE + 0x9000)
#define APCS_L2_SAW2_BASE (APPS_SS_BASE + 0x12000)
#define PERIPH_SS_BASE 0x07800000
#define MSM_SDC1_BASE (PERIPH_SS_BASE + 0x00024000)
#define MSM_SDC1_SDHCI_BASE (PERIPH_SS_BASE + 0x00024900)
#define MSM_SDC2_BASE (PERIPH_SS_BASE + 0x00064000)
#define MSM_SDC2_SDHCI_BASE (PERIPH_SS_BASE + 0x00064900)
/* SDHCI */
#define SDCC_MCI_HC_MODE (0x00000078)
#define SDCC_HC_PWRCTL_STATUS_REG (0x000000DC)
#define SDCC_HC_PWRCTL_MASK_REG (0x000000E0)
#define SDCC_HC_PWRCTL_CLEAR_REG (0x000000E4)
#define SDCC_HC_PWRCTL_CTL_REG (0x000000E8)
#define BLSP1_UART0_BASE (PERIPH_SS_BASE + 0x000AF000)
#define BLSP1_UART1_BASE (PERIPH_SS_BASE + 0x000B0000)
#define MSM_USB_BASE (PERIPH_SS_BASE + 0x000D9000)
#define CLK_CTL_BASE 0x1800000
#define SPMI_BASE 0x02000000
#define SPMI_GENI_BASE (SPMI_BASE + 0xA000)
#define SPMI_PIC_BASE (SPMI_BASE + 0x01800000)
#define PMIC_ARB_CORE 0x200F000
#define TLMM_BASE_ADDR 0x1000000
#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + (x)*0x1000)
#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x00000004 + (x)*0x1000)
#define MPM2_MPM_CTRL_BASE 0x004A0000
#define MPM2_MPM_PS_HOLD 0x004AB000
#define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL 0x004A3000
/* CRYPTO ENGINE */
#define MSM_CE1_BASE 0x073A000
#define MSM_CE1_BAM_BASE 0x0704000
#define GCC_CRYPTO_BCR (CLK_CTL_BASE + 0x16000)
#define GCC_CRYPTO_CMD_RCGR (CLK_CTL_BASE + 0x16004)
#define GCC_CRYPTO_CFG_RCGR (CLK_CTL_BASE + 0x16008)
#define GCC_CRYPTO_CBCR (CLK_CTL_BASE + 0x1601C)
#define GCC_CRYPTO_AXI_CBCR (CLK_CTL_BASE + 0x16020)
#define GCC_CRYPTO_AHB_CBCR (CLK_CTL_BASE + 0x16024)
/* I2C */
#define BLSP_QUP_BASE(blsp_id, qup_id) (PERIPH_SS_BASE + 0xB5000 + 0x1000 * qup_id)
#define GCC_BLSP1_QUP2_APPS_CBCR (CLK_CTL_BASE + 0x3010)
#define GCC_BLSP1_QUP2_CFG_RCGR (CLK_CTL_BASE + 0x3018)
#define GCC_BLSP1_QUP2_CMD_RCGR (CLK_CTL_BASE + 0x3014)
/* GPLL */
#define GPLL0_STATUS (CLK_CTL_BASE + 0x2101C)
#define GPLL1_STATUS (CLK_CTL_BASE + 0x2001C)
#define APCS_GPLL_ENA_VOTE (CLK_CTL_BASE + 0x45000)
#define APCS_CLOCK_BRANCH_ENA_VOTE (CLK_CTL_BASE + 0x45004)
/* SDCC */
#define SDC1_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x10A000)
#define SDCC1_BCR (CLK_CTL_BASE + 0x42000) /* block reset*/
#define SDCC1_APPS_CBCR (CLK_CTL_BASE + 0x42018) /* branch ontrol */
#define SDCC1_AHB_CBCR (CLK_CTL_BASE + 0x4201C)
#define SDCC1_CMD_RCGR (CLK_CTL_BASE + 0x42004) /* cmd */
#define SDCC1_CFG_RCGR (CLK_CTL_BASE + 0x42008) /* cfg */
#define SDCC1_M (CLK_CTL_BASE + 0x4200C) /* m */
#define SDCC1_N (CLK_CTL_BASE + 0x42010) /* n */
#define SDCC1_D (CLK_CTL_BASE + 0x42014) /* d */
#define SDC2_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x109000)
#define SDCC2_BCR (CLK_CTL_BASE + 0x43000) /* block reset */
#define SDCC2_APPS_CBCR (CLK_CTL_BASE + 0x43018) /* branch control */
#define SDCC2_AHB_CBCR (CLK_CTL_BASE + 0x4301C)
#define SDCC2_CMD_RCGR (CLK_CTL_BASE + 0x43004) /* cmd */
#define SDCC2_CFG_RCGR (CLK_CTL_BASE + 0x43008) /* cfg */
#define SDCC2_M (CLK_CTL_BASE + 0x4300C) /* m */
#define SDCC2_N (CLK_CTL_BASE + 0x43010) /* n */
#define SDCC2_D (CLK_CTL_BASE + 0x43014) /* d */
/* UART */
#define BLSP1_AHB_CBCR (CLK_CTL_BASE + 0x1008)
#define BLSP1_UART1_APPS_CBCR (CLK_CTL_BASE + 0x203C)
#define BLSP1_UART1_APPS_CMD_RCGR (CLK_CTL_BASE + 0x2044)
#define BLSP1_UART1_APPS_CFG_RCGR (CLK_CTL_BASE + 0x2048)
#define BLSP1_UART1_APPS_M (CLK_CTL_BASE + 0x204C)
#define BLSP1_UART1_APPS_N (CLK_CTL_BASE + 0x2050)
#define BLSP1_UART1_APPS_D (CLK_CTL_BASE + 0x2054)
#define BLSP1_UART2_APPS_CBCR (CLK_CTL_BASE + 0x302C)
#define BLSP1_UART2_APPS_CMD_RCGR (CLK_CTL_BASE + 0x3034)
#define BLSP1_UART2_APPS_CFG_RCGR (CLK_CTL_BASE + 0x3038)
#define BLSP1_UART2_APPS_M (CLK_CTL_BASE + 0x303C)
#define BLSP1_UART2_APPS_N (CLK_CTL_BASE + 0x3040)
#define BLSP1_UART2_APPS_D (CLK_CTL_BASE + 0x3044)
/* USB */
#define USB_HS_BCR (CLK_CTL_BASE + 0x41000)
#define USB_HS_SYSTEM_CBCR (CLK_CTL_BASE + 0x41004)
#define USB_HS_AHB_CBCR (CLK_CTL_BASE + 0x41008)
#define USB_HS_SYSTEM_CMD_RCGR (CLK_CTL_BASE + 0x41010)
#define USB_HS_SYSTEM_CFG_RCGR (CLK_CTL_BASE + 0x41014)
/* RPMB send receive buffer needs to be mapped
* as device memory, define the start address
* and size in MB
*/
#define RPMB_SND_RCV_BUF 0x90000000
#define RPMB_SND_RCV_BUF_SZ 0x1
/* QSEECOM: Secure app region notification */
#define APP_REGION_ADDR 0x86000000
#define APP_REGION_SIZE 0x300000
/* MDSS */
#define MIPI_DSI_BASE (0x1A98000)
#define MIPI_DSI0_BASE MIPI_DSI_BASE
#define MIPI_DSI1_BASE (0x1AA0000)
#define DSI0_PHY_BASE (0x1A98500)
#define DSI1_PHY_BASE (0x1AA0500)
#define DSI0_PLL_BASE (0x1A98300)
#define DSI1_PLL_BASE DSI0_PLL_BASE
#define REG_DSI(off) (MIPI_DSI_BASE + 0x04 + (off))
#define MDP_BASE (0x1A00000)
#define REG_MDP(off) (MDP_BASE + (off))
#define MDP_HW_REV REG_MDP(0x1000)
#define MDP_VP_0_VIG_0_BASE REG_MDP(0x5000)
#define MDP_VP_0_VIG_1_BASE REG_MDP(0x7000)
#define MDP_VP_0_RGB_0_BASE REG_MDP(0x15000)
#define MDP_VP_0_RGB_1_BASE REG_MDP(0x17000)
#define MDP_VP_0_DMA_0_BASE REG_MDP(0x25000)
#define MDP_VP_0_DMA_1_BASE REG_MDP(0x27000)
#define MDP_VP_0_MIXER_0_BASE REG_MDP(0x45000)
#define MDP_VP_0_MIXER_1_BASE REG_MDP(0x46000)
#define MDP_DISP_INTF_SEL REG_MDP(0x1004)
#define MDP_VIDEO_INTF_UNDERFLOW_CTL REG_MDP(0x12E0)
#define MDP_UPPER_NEW_ROI_PRIOR_RO_START REG_MDP(0x11EC)
#define MDP_LOWER_NEW_ROI_PRIOR_TO_START REG_MDP(0x13F8)
#define MDP_CTL_0_BASE REG_MDP(0x2000)
#define MDP_CTL_1_BASE REG_MDP(0x2200)
#define MDP_CLK_CTRL0 REG_MDP(0x012AC)
#define MDP_CLK_CTRL1 REG_MDP(0x012B4)
#define MDP_CLK_CTRL2 REG_MDP(0x012BC)
#define MDP_CLK_CTRL3 REG_MDP(0x013A8)
#define MDP_CLK_CTRL4 REG_MDP(0x013B0)
#define MDP_CLK_CTRL5 REG_MDP(0x013B8)
#define MDP_INTF_0_BASE REG_MDP(0x11F00)
#define MDP_INTF_1_BASE REG_MDP(0x12700)
#define MDP_INTF_2_BASE REG_MDP(0x12F00)
#define MDP_REG_SPLIT_DISPLAY_EN REG_MDP(0x12f4)
#define MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL REG_MDP(0x12F8)
#define MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL REG_MDP(0x13F0)
#define MDP_REG_PPB0_CNTL REG_MDP(0x1420)
#define MDP_REG_PPB0_CONFIG REG_MDP(0x1424)
#define MMSS_MDP_SMP_ALLOC_W_BASE REG_MDP(0x1080)
#define MMSS_MDP_SMP_ALLOC_R_BASE REG_MDP(0x1130)
#define MDP_QOS_REMAPPER_CLASS_0 REG_MDP(0x11E0)
#define VBIF_VBIF_DDR_FORCE_CLK_ON REG_MDP(0xc8004)
#define VBIF_VBIF_DDR_OUT_MAX_BURST REG_MDP(0xc80D8)
#define VBIF_VBIF_DDR_ARB_CTRL REG_MDP(0xc80F0)
#define VBIF_VBIF_DDR_RND_RBN_QOS_ARB REG_MDP(0xc8124)
#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0 REG_MDP(0xc8160)
#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1 REG_MDP(0xc8164)
#define VBIF_VBIF_DDR_OUT_AOOO_AXI_EN REG_MDP(0xc8178)
#define VBIF_VBIF_DDR_OUT_AX_AOOO REG_MDP(0xc817C)
#define VBIF_VBIF_IN_RD_LIM_CONF0 REG_MDP(0xc80B0)
#define VBIF_VBIF_IN_RD_LIM_CONF1 REG_MDP(0xc80B4)
#define VBIF_VBIF_IN_RD_LIM_CONF2 REG_MDP(0xc80B8)
#define VBIF_VBIF_IN_RD_LIM_CONF3 REG_MDP(0xc80BC)
#define VBIF_VBIF_IN_WR_LIM_CONF0 REG_MDP(0xc80C0)
#define VBIF_VBIF_IN_WR_LIM_CONF1 REG_MDP(0xc80C4)
#define VBIF_VBIF_IN_WR_LIM_CONF2 REG_MDP(0xc80C8)
#define VBIF_VBIF_IN_WR_LIM_CONF3 REG_MDP(0xc80CC)
#define VBIF_VBIF_ABIT_SHORT REG_MDP(0xc8070)
#define VBIF_VBIF_ABIT_SHORT_CONF REG_MDP(0xc8074)
#define VBIF_VBIF_GATE_OFF_WRREQ_EN REG_MDP(0xc80A8)
#define SOFT_RESET 0x118
#define CLK_CTRL 0x11C
#define TRIG_CTRL 0x084
#define CTRL 0x004
#define COMMAND_MODE_DMA_CTRL 0x03C
#define COMMAND_MODE_MDP_CTRL 0x040
#define COMMAND_MODE_MDP_DCS_CMD_CTRL 0x044
#define COMMAND_MODE_MDP_STREAM0_CTRL 0x058
#define COMMAND_MODE_MDP_STREAM0_TOTAL 0x05C
#define COMMAND_MODE_MDP_STREAM1_CTRL 0x060
#define COMMAND_MODE_MDP_STREAM1_TOTAL 0x064
#define ERR_INT_MASK0 0x10C
#define LANE_CTL 0x0AC
#define LANE_SWAP_CTL 0x0B0
#define TIMING_CTL 0x0C4
#define VIDEO_MODE_ACTIVE_H 0x024
#define VIDEO_MODE_ACTIVE_V 0x028
#define VIDEO_MODE_TOTAL 0x02C
#define VIDEO_MODE_HSYNC 0x030
#define VIDEO_MODE_VSYNC 0x034
#define VIDEO_MODE_VSYNC_VPOS 0x038
#define DMA_CMD_OFFSET 0x048
#define DMA_CMD_LENGTH 0x04C
#define INT_CTRL 0x110
#define CMD_MODE_DMA_SW_TRIGGER 0x090
#define EOT_PACKET_CTRL 0x0CC
#define MISR_CMD_CTRL 0x0A0
#define MISR_VIDEO_CTRL 0x0A4
#define VIDEO_MODE_CTRL 0x010
#define HS_TIMER_CTRL 0x0BC
#define TCSR_TZ_WONCE 0x193D000
#define TCSR_BOOT_MISC_DETECT 0x193D100
#define BOOT_ROM_BASE 0x00100000
#define BOOT_ROM_END 0x00124000 /* Crashes when reading more */
#endif

View File

@ -0,0 +1,68 @@
/* Copyright (c) 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.
*/
#ifndef __IRQS_MSM8916_H
#define __IRQS_MSM8916_H
/* MSM ACPU Interrupt Numbers */
/* 0-15: STI/SGI (software triggered/generated interrupts)
* 16-31: PPI (private peripheral interrupts)
* 32+: SPI (shared peripheral interrupts)
*/
int qtmr_irq();
#define GIC_PPI_START 16
#define GIC_SPI_START 32
#define INT_QTMR_NON_SECURE_PHY_TIMER_EXP (GIC_PPI_START + 3)
#define INT_QTMR_VIRTUAL_TIMER_EXP (GIC_PPI_START + 4)
#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP qtmr_irq()
#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP_8x16 (GIC_SPI_START + 8)
#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP_8x39 (GIC_SPI_START + 257)
#define SDCC1_PWRCTL_IRQ (GIC_SPI_START + 138)
#define SDCC2_PWRCTL_IRQ (GIC_SPI_START + 221)
#define USB1_HS_BAM_IRQ (GIC_SPI_START + 135)
#define USB1_HS_IRQ (GIC_SPI_START + 134)
/* Retrofit universal macro names */
#define INT_USB_HS USB1_HS_IRQ
#define EE0_KRAIT_HLOS_SPMI_PERIPH_IRQ (GIC_SPI_START + 190)
#define NR_MSM_IRQS 256
#define NR_GPIO_IRQS 173
#define NR_BOARD_IRQS 0
#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + \
NR_BOARD_IRQS)
#define BLSP_QUP_IRQ(blsp_id, qup_id) (GIC_SPI_START + 95 + qup_id)
#endif /* __IRQS_MSM8916_H */

View File

@ -0,0 +1,41 @@
#ifndef __QCOM_PROTOCOL_CLOCK_H__
#define __QCOM_PROTOCOL_CLOCK_H__
#include <Chipset/clock.h>
#define QCOM_CLOCK_PROTOCOL_GUID \
{ \
0x4fcc91c2, 0x9c4f, 0x4e3c, \
{ \
0xa6, 0x73, 0xc6, 0xdf, 0x62, 0xe0, 0x41, 0xd5 \
} \
}
typedef struct _QCOM_CLOCK_PROTOCOL QCOM_CLOCK_PROTOCOL;
typedef struct clk *(EFIAPI *clk_get_t)(const char *id);
typedef int(EFIAPI *clk_enable_t)(struct clk *clk);
typedef void(EFIAPI *clk_disable_t)(struct clk *clk);
typedef unsigned long(EFIAPI *clk_get_rate_t)(struct clk *clk);
typedef int(EFIAPI *clk_set_rate_t)(struct clk *clk, unsigned long rate);
typedef int(EFIAPI *clk_set_parent_t)(struct clk *clk, struct clk *parent);
typedef struct clk *(EFIAPI *clk_get_parent_t)(struct clk *clk);
typedef int(EFIAPI *clk_get_set_enable_t)(
char *id, unsigned long rate, bool enable);
typedef int(EFIAPI *clk_reset_t)(struct clk *clk, enum clk_reset_action);
struct _QCOM_CLOCK_PROTOCOL {
clk_get_t clk_get;
clk_enable_t clk_enable;
clk_disable_t clk_disable;
clk_get_rate_t clk_get_rate;
clk_set_rate_t clk_set_rate;
clk_set_parent_t clk_set_parent;
clk_get_parent_t clk_get_parent;
clk_get_set_enable_t clk_get_set_enable;
clk_reset_t clk_reset;
};
extern EFI_GUID gQcomClockProtocolGuid;
#endif

View File

@ -0,0 +1,24 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = QcomPlatformClockInitLib
FILE_GUID = 6B439EE9-31E2-4486-A95F-0AF5FAA31599
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = QcomPlatformClockInitLib
[Sources]
msm8916-clock.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
IoLib
ArmLib
[BuildOptions.AARCH64]
GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-overflow -Wno-int-conversion

View File

@ -0,0 +1,612 @@
/* 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 <Library/LKEnvLib.h>
#include <Chipset/clock.h>
#include <Chipset/clock_pll.h>
#include <Chipset/clock_lib2.h>
#include <Platform/clock.h>
#include <Platform/iomap.h>
/* Mux source select values */
#define cxo_source_val 0
#define gpll0_source_val 1
#define cxo_mm_source_val 0
#define gpll0_mm_source_val 5
#define gpll1_mm_source_val 1
struct clk_freq_tbl rcg_dummy_freq = F_END;
/* Clock Operations */
static struct clk_ops clk_ops_branch =
{
.enable = clock_lib2_branch_clk_enable,
.disable = clock_lib2_branch_clk_disable,
.set_rate = clock_lib2_branch_set_rate,
};
static struct clk_ops clk_ops_rcg_mnd =
{
.enable = clock_lib2_rcg_enable,
.set_rate = clock_lib2_rcg_set_rate,
};
static struct clk_ops clk_ops_rcg =
{
.enable = clock_lib2_rcg_enable,
.set_rate = clock_lib2_rcg_set_rate,
};
static struct clk_ops clk_ops_cxo =
{
.enable = cxo_clk_enable,
.disable = cxo_clk_disable,
};
static struct clk_ops clk_ops_pll_vote =
{
.enable = pll_vote_clk_enable,
.disable = pll_vote_clk_disable,
.auto_off = pll_vote_clk_disable,
.is_enabled = pll_vote_clk_is_enabled,
};
static struct clk_ops clk_ops_vote =
{
.enable = clock_lib2_vote_clk_enable,
.disable = clock_lib2_vote_clk_disable,
};
/* Clock Sources */
static struct fixed_clk cxo_clk_src =
{
.c = {
.rate = 19200000,
.dbg_name = "cxo_clk_src",
.ops = &clk_ops_cxo,
},
};
static struct pll_vote_clk gpll0_clk_src =
{
.en_reg = (void *) APCS_GPLL_ENA_VOTE,
.en_mask = BIT(0),
.status_reg = (void *) GPLL0_STATUS,
.status_mask = BIT(17),
.parent = &cxo_clk_src.c,
.c = {
.rate = 800000000,
.dbg_name = "gpll0_clk_src",
.ops = &clk_ops_pll_vote,
},
};
/* SDCC Clocks */
static struct clk_freq_tbl ftbl_gcc_sdcc1_2_apps_clk[] =
{
F( 144000, cxo, 16, 3, 25),
F( 400000, cxo, 12, 1, 4),
F( 20000000, gpll0, 10, 1, 4),
F( 25000000, gpll0, 16, 1, 2),
F( 50000000, gpll0, 16, 0, 0),
F(100000000, gpll0, 8, 0, 0),
F(177770000, gpll0, 4.5, 0, 0),
F(200000000, gpll0, 4, 0, 0),
F_END
};
static struct rcg_clk sdcc1_apps_clk_src =
{
.cmd_reg = (uint32_t *) SDCC1_CMD_RCGR,
.cfg_reg = (uint32_t *) SDCC1_CFG_RCGR,
.m_reg = (uint32_t *) SDCC1_M,
.n_reg = (uint32_t *) SDCC1_N,
.d_reg = (uint32_t *) SDCC1_D,
.set_rate = clock_lib2_rcg_set_rate_mnd,
.freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "sdc1_clk",
.ops = &clk_ops_rcg_mnd,
},
};
/* BLSP1_QUP2 Clocks */
static struct clk_freq_tbl ftbl_gcc_blsp1_qup2_i2c_apps_clk_src[] =
{
F( 96000, cxo, 10, 1, 2),
F( 4800000, cxo, 4, 0, 0),
F( 9600000, cxo, 2, 0, 0),
F( 16000000, gpll0, 10, 1, 5),
F( 19200000, gpll0, 1, 0, 0),
F( 25000000, gpll0, 16, 1, 2),
F( 50000000, gpll0, 16, 0, 0),
F_END
};
static struct branch_clk gcc_sdcc1_apps_clk =
{
.cbcr_reg = (uint32_t *) SDCC1_APPS_CBCR,
.parent = &sdcc1_apps_clk_src.c,
.c = {
.dbg_name = "gcc_sdcc1_apps_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gcc_sdcc1_ahb_clk =
{
.cbcr_reg = (uint32_t *) SDCC1_AHB_CBCR,
.has_sibling = 1,
.c = {
.dbg_name = "gcc_sdcc1_ahb_clk",
.ops = &clk_ops_branch,
},
};
static struct rcg_clk sdcc2_apps_clk_src =
{
.cmd_reg = (uint32_t *) SDCC2_CMD_RCGR,
.cfg_reg = (uint32_t *) SDCC2_CFG_RCGR,
.m_reg = (uint32_t *) SDCC2_M,
.n_reg = (uint32_t *) SDCC2_N,
.d_reg = (uint32_t *) SDCC2_D,
.set_rate = clock_lib2_rcg_set_rate_mnd,
.freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "sdc2_clk",
.ops = &clk_ops_rcg_mnd,
},
};
static struct branch_clk gcc_sdcc2_apps_clk =
{
.cbcr_reg = (uint32_t *) SDCC2_APPS_CBCR,
.parent = &sdcc2_apps_clk_src.c,
.c = {
.dbg_name = "gcc_sdcc2_apps_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gcc_sdcc2_ahb_clk =
{
.cbcr_reg = (uint32_t *) SDCC2_AHB_CBCR,
.has_sibling = 1,
.c = {
.dbg_name = "gcc_sdcc2_ahb_clk",
.ops = &clk_ops_branch,
},
};
/* UART Clocks */
static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] =
{
F( 3686400, gpll0, 1, 72, 15625),
F( 7372800, gpll0, 1, 144, 15625),
F(14745600, gpll0, 1, 288, 15625),
F(16000000, gpll0, 10, 1, 5),
F(19200000, cxo, 1, 0, 0),
F(24000000, gpll0, 1, 3, 100),
F(25000000, gpll0, 16, 1, 2),
F(32000000, gpll0, 1, 1, 25),
F(40000000, gpll0, 1, 1, 20),
F(46400000, gpll0, 1, 29, 500),
F(48000000, gpll0, 1, 3, 50),
F(51200000, gpll0, 1, 8, 125),
F(56000000, gpll0, 1, 7, 100),
F(58982400, gpll0, 1,1152, 15625),
F(60000000, gpll0, 1, 3, 40),
F_END
};
static struct rcg_clk blsp1_uart1_apps_clk_src =
{
.cmd_reg = (uint32_t *) BLSP1_UART1_APPS_CMD_RCGR,
.cfg_reg = (uint32_t *) BLSP1_UART1_APPS_CFG_RCGR,
.m_reg = (uint32_t *) BLSP1_UART1_APPS_M,
.n_reg = (uint32_t *) BLSP1_UART1_APPS_N,
.d_reg = (uint32_t *) BLSP1_UART1_APPS_D,
.set_rate = clock_lib2_rcg_set_rate_mnd,
.freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "blsp1_uart1_apps_clk",
.ops = &clk_ops_rcg_mnd,
},
};
static struct branch_clk gcc_blsp1_uart1_apps_clk =
{
.cbcr_reg = (uint32_t *) BLSP1_UART1_APPS_CBCR,
.parent = &blsp1_uart1_apps_clk_src.c,
.c = {
.dbg_name = "gcc_blsp1_uart1_apps_clk",
.ops = &clk_ops_branch,
},
};
static struct rcg_clk blsp1_uart2_apps_clk_src =
{
.cmd_reg = (uint32_t *) BLSP1_UART2_APPS_CMD_RCGR,
.cfg_reg = (uint32_t *) BLSP1_UART2_APPS_CFG_RCGR,
.m_reg = (uint32_t *) BLSP1_UART2_APPS_M,
.n_reg = (uint32_t *) BLSP1_UART2_APPS_N,
.d_reg = (uint32_t *) BLSP1_UART2_APPS_D,
.set_rate = clock_lib2_rcg_set_rate_mnd,
.freq_tbl = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "blsp1_uart2_apps_clk",
.ops = &clk_ops_rcg_mnd,
},
};
static struct branch_clk gcc_blsp1_uart2_apps_clk =
{
.cbcr_reg = (uint32_t *) BLSP1_UART2_APPS_CBCR,
.parent = &blsp1_uart2_apps_clk_src.c,
.c = {
.dbg_name = "gcc_blsp1_uart2_apps_clk",
.ops = &clk_ops_branch,
},
};
static struct vote_clk gcc_blsp1_ahb_clk = {
.cbcr_reg = (uint32_t *) BLSP1_AHB_CBCR,
.vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(10),
.c = {
.dbg_name = "gcc_blsp1_ahb_clk",
.ops = &clk_ops_vote,
},
};
/* USB Clocks */
static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] =
{
F(80000000, gpll0, 10, 0, 0),
F_END
};
static struct rcg_clk usb_hs_system_clk_src =
{
.cmd_reg = (uint32_t *) USB_HS_SYSTEM_CMD_RCGR,
.cfg_reg = (uint32_t *) USB_HS_SYSTEM_CFG_RCGR,
.set_rate = clock_lib2_rcg_set_rate_hid,
.freq_tbl = ftbl_gcc_usb_hs_system_clk,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "usb_hs_system_clk",
.ops = &clk_ops_rcg,
},
};
static struct branch_clk gcc_usb_hs_system_clk =
{
.cbcr_reg = (uint32_t *) USB_HS_SYSTEM_CBCR,
.parent = &usb_hs_system_clk_src.c,
.c = {
.dbg_name = "gcc_usb_hs_system_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk gcc_usb_hs_ahb_clk =
{
.cbcr_reg = (uint32_t *) USB_HS_AHB_CBCR,
.has_sibling = 1,
.c = {
.dbg_name = "gcc_usb_hs_ahb_clk",
.ops = &clk_ops_branch,
},
};
/* Display clocks */
static struct clk_freq_tbl ftbl_mdss_esc0_1_clk[] = {
F_MM(19200000, cxo, 1, 0, 0),
F_END
};
static struct clk_freq_tbl ftbl_mdss_esc1_1_clk[] = {
F_MM(19200000, cxo, 1, 0, 0),
F_END
};
static struct clk_freq_tbl ftbl_mdp_clk[] = {
F( 80000000, gpll0, 10, 0, 0),
F( 100000000, gpll0, 8, 0, 0),
F( 200000000, gpll0, 4, 0, 0),
F( 320000000, gpll0, 2.5, 0, 0),
F_END
};
static struct rcg_clk dsi_esc0_clk_src = {
.cmd_reg = (uint32_t *) DSI_ESC0_CMD_RCGR,
.cfg_reg = (uint32_t *) DSI_ESC0_CFG_RCGR,
.set_rate = clock_lib2_rcg_set_rate_hid,
.freq_tbl = ftbl_mdss_esc0_1_clk,
.c = {
.dbg_name = "dsi_esc0_clk_src",
.ops = &clk_ops_rcg,
},
};
static struct rcg_clk dsi_esc1_clk_src = {
.cmd_reg = (uint32_t *) DSI_ESC1_CMD_RCGR,
.cfg_reg = (uint32_t *) DSI_ESC1_CFG_RCGR,
.set_rate = clock_lib2_rcg_set_rate_hid,
.freq_tbl = ftbl_mdss_esc1_1_clk,
.c = {
.dbg_name = "dsi_esc1_clk_src",
.ops = &clk_ops_rcg,
},
};
static struct clk_freq_tbl ftbl_mdss_vsync_clk[] = {
F_MM(19200000, cxo, 1, 0, 0),
F_END
};
static struct rcg_clk vsync_clk_src = {
.cmd_reg = (uint32_t *) VSYNC_CMD_RCGR,
.cfg_reg = (uint32_t *) VSYNC_CFG_RCGR,
.set_rate = clock_lib2_rcg_set_rate_hid,
.freq_tbl = ftbl_mdss_vsync_clk,
.c = {
.dbg_name = "vsync_clk_src",
.ops = &clk_ops_rcg,
},
};
static struct branch_clk mdss_esc0_clk = {
.cbcr_reg = (uint32_t *) DSI_ESC0_CBCR,
.parent = &dsi_esc0_clk_src.c,
.has_sibling = 0,
.c = {
.dbg_name = "mdss_esc0_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk mdss_esc1_clk = {
.cbcr_reg = (uint32_t *) DSI_ESC1_CBCR,
.parent = &dsi_esc1_clk_src.c,
.has_sibling = 0,
.c = {
.dbg_name = "mdss_esc1_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk mdss_axi_clk = {
.cbcr_reg = (uint32_t *) MDP_AXI_CBCR,
.has_sibling = 1,
.c = {
.dbg_name = "mdss_axi_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk mdp_ahb_clk = {
.cbcr_reg = (uint32_t *) MDP_AHB_CBCR,
.has_sibling = 1,
.c = {
.dbg_name = "mdp_ahb_clk",
.ops = &clk_ops_branch,
},
};
static struct rcg_clk mdss_mdp_clk_src = {
.cmd_reg = (uint32_t *) MDP_CMD_RCGR,
.cfg_reg = (uint32_t *) MDP_CFG_RCGR,
.set_rate = clock_lib2_rcg_set_rate_hid,
.freq_tbl = ftbl_mdp_clk,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "mdss_mdp_clk_src",
.ops = &clk_ops_rcg,
},
};
static struct branch_clk mdss_mdp_clk = {
.cbcr_reg = (uint32_t *) MDP_CBCR,
.parent = &mdss_mdp_clk_src.c,
.has_sibling = 0,
.c = {
.dbg_name = "mdss_mdp_clk",
.ops = &clk_ops_branch,
},
};
static struct branch_clk mdss_vsync_clk = {
.cbcr_reg = MDSS_VSYNC_CBCR,
.parent = &vsync_clk_src.c,
.has_sibling = 0,
.c = {
.dbg_name = "mdss_vsync_clk",
.ops = &clk_ops_branch,
},
};
static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
F(160000000, gpll0, 5, 0, 0),
F_END
};
static struct rcg_clk ce1_clk_src = {
.cmd_reg = (uint32_t *) GCC_CRYPTO_CMD_RCGR,
.cfg_reg = (uint32_t *) GCC_CRYPTO_CFG_RCGR,
.set_rate = clock_lib2_rcg_set_rate_hid,
.freq_tbl = ftbl_gcc_ce1_clk,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "ce1_clk_src",
.ops = &clk_ops_rcg,
},
};
static struct vote_clk gcc_ce1_clk = {
.cbcr_reg = (uint32_t *) GCC_CRYPTO_CBCR,
.vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(2),
.c = {
.dbg_name = "gcc_ce1_clk",
.ops = &clk_ops_vote,
},
};
static struct vote_clk gcc_ce1_ahb_clk = {
.cbcr_reg = (uint32_t *) GCC_CRYPTO_AHB_CBCR,
.vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(0),
.c = {
.dbg_name = "gcc_ce1_ahb_clk",
.ops = &clk_ops_vote,
},
};
static struct vote_clk gcc_ce1_axi_clk = {
.cbcr_reg = (uint32_t *) GCC_CRYPTO_AXI_CBCR,
.vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
.en_mask = BIT(1),
.c = {
.dbg_name = "gcc_ce1_axi_clk",
.ops = &clk_ops_vote,
},
};
static struct rcg_clk gcc_blsp1_qup2_i2c_apps_clk_src =
{
.cmd_reg = (uint32_t *) GCC_BLSP1_QUP2_CMD_RCGR,
.cfg_reg = (uint32_t *) GCC_BLSP1_QUP2_CFG_RCGR,
.set_rate = clock_lib2_rcg_set_rate_hid,
.freq_tbl = ftbl_gcc_blsp1_qup2_i2c_apps_clk_src,
.current_freq = &rcg_dummy_freq,
.c = {
.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk_src",
.ops = &clk_ops_rcg,
},
};
static struct branch_clk gcc_blsp1_qup2_i2c_apps_clk = {
.cbcr_reg = GCC_BLSP1_QUP2_APPS_CBCR,
.parent = &gcc_blsp1_qup2_i2c_apps_clk_src.c,
.c = {
.dbg_name = "gcc_blsp1_qup2_i2c_apps_clk",
.ops = &clk_ops_branch,
},
};
/* Clock lookup table */
static struct clk_lookup msm_clocks_8916[] =
{
CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
CLK_LOOKUP("sdc1_core_clk", gcc_sdcc1_apps_clk.c),
CLK_LOOKUP("sdc2_iface_clk", gcc_sdcc2_ahb_clk.c),
CLK_LOOKUP("sdc2_core_clk", gcc_sdcc2_apps_clk.c),
CLK_LOOKUP("uart1_iface_clk", gcc_blsp1_ahb_clk.c),
CLK_LOOKUP("uart1_core_clk", gcc_blsp1_uart1_apps_clk.c),
CLK_LOOKUP("uart2_iface_clk", gcc_blsp1_ahb_clk.c),
CLK_LOOKUP("uart2_core_clk", gcc_blsp1_uart2_apps_clk.c),
CLK_LOOKUP("usb_iface_clk", gcc_usb_hs_ahb_clk.c),
CLK_LOOKUP("usb_core_clk", gcc_usb_hs_system_clk.c),
CLK_LOOKUP("mdp_ahb_clk", mdp_ahb_clk.c),
CLK_LOOKUP("mdss_esc0_clk", mdss_esc0_clk.c),
CLK_LOOKUP("mdss_esc1_clk", mdss_esc1_clk.c),
CLK_LOOKUP("mdss_axi_clk", mdss_axi_clk.c),
CLK_LOOKUP("mdss_vsync_clk", mdss_vsync_clk.c),
CLK_LOOKUP("mdss_mdp_clk_src", mdss_mdp_clk_src.c),
CLK_LOOKUP("mdss_mdp_clk", mdss_mdp_clk.c),
CLK_LOOKUP("ce1_ahb_clk", gcc_ce1_ahb_clk.c),
CLK_LOOKUP("ce1_axi_clk", gcc_ce1_axi_clk.c),
CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),
CLK_LOOKUP("ce1_src_clk", ce1_clk_src.c),
CLK_LOOKUP("blsp1_qup2_ahb_iface_clk", gcc_blsp1_ahb_clk.c),
CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk_src", gcc_blsp1_qup2_i2c_apps_clk_src.c),
CLK_LOOKUP("gcc_blsp1_qup2_i2c_apps_clk", gcc_blsp1_qup2_i2c_apps_clk.c),
};
RETURN_STATUS
EFIAPI
LibQcomPlatformClockInit (
struct clk_lookup **clist,
unsigned *num
)
{
*clist = msm_clocks_8916;
*num = ARRAY_SIZE(msm_clocks_8916);
return RETURN_SUCCESS;
}

View File

@ -33,6 +33,7 @@
[Protocols]
gEFIDroidKeypadDeviceProtocolGuid = { 0xb27625b5, 0x0b6c, 0x4614, { 0xaa, 0x3c, 0x33, 0x13, 0xb5, 0x1d, 0x36, 0x46 } }
gQcomClockProtocolGuid = { 0x4fcc91c2, 0x9c4f, 0x4e3c, { 0xa6, 0x73, 0xc6, 0xdf, 0x62, 0xe0, 0x41, 0xd5 } }
[PcdsFixedAtBuild.common]
# Simple FrameBuffer

View File

@ -72,6 +72,9 @@
MemoryInitPeiLib|MSM8916Pkg/Library/MemoryInitPeiLib/PeiMemoryAllocationLib.inf
PlatformPeiLib|MSM8916Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
# SoC Drivers
QcomPlatformClockInitLib|MSM8916Pkg/Library/QcomPlatformClockInitLib/QcomPlatformClockInitLib.inf
[LibraryClasses.common.SEC]
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
@ -79,6 +82,22 @@
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
# SoC Drivers
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockImplLib.inf
[LibraryClasses.common.DXE_DRIVER]
# SoC Drivers
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
# SoC Drivers
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
[LibraryClasses.common.UEFI_DRIVER]
# SoC Drivers
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
################################################################################
#
# Pcd Section - list of all EDK II PCD Entries defined by this Platform
@ -180,9 +199,11 @@
MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
#
# GPIO
# SoC Drivers
#
MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
#
# Virtual Keyboard
#

View File

@ -153,6 +153,10 @@ READ_LOCK_STATUS = TRUE
INF MSM8916Pkg/Drivers/MSM8916PkgDxe/MSM8916PkgDxe.inf
INF MSM8916Pkg/Drivers/SimpleFbDxe/SimpleFbDxe.inf
#
# SoC Drivers
#
INF MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
#
# USB Host Support