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:
parent
7e44ba1051
commit
c2681ce7d9
35
MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
Normal file
35
MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
Normal 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
|
26
MSM8916Pkg/Drivers/ClockDxe/ClockImplLib.inf
Normal file
26
MSM8916Pkg/Drivers/ClockDxe/ClockImplLib.inf
Normal 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
|
28
MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
Normal file
28
MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
Normal 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
|
22
MSM8916Pkg/Drivers/ClockDxe/Driver.c
Normal file
22
MSM8916Pkg/Drivers/ClockDxe/Driver.c
Normal 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;
|
||||||
|
}
|
20
MSM8916Pkg/Drivers/ClockDxe/LibraryBS.c
Normal file
20
MSM8916Pkg/Drivers/ClockDxe/LibraryBS.c
Normal 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;
|
||||||
|
}
|
33
MSM8916Pkg/Drivers/ClockDxe/LibraryImpl.c
Normal file
33
MSM8916Pkg/Drivers/ClockDxe/LibraryImpl.c
Normal 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;
|
||||||
|
}
|
3
MSM8916Pkg/Drivers/ClockDxe/Source.txt
Normal file
3
MSM8916Pkg/Drivers/ClockDxe/Source.txt
Normal 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
|
387
MSM8916Pkg/Drivers/ClockDxe/clock-local.c
Normal file
387
MSM8916Pkg/Drivers/ClockDxe/clock-local.c
Normal 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.
|
||||||
|
*/
|
||||||
|
}
|
193
MSM8916Pkg/Drivers/ClockDxe/clock.c
Normal file
193
MSM8916Pkg/Drivers/ClockDxe/clock.c
Normal 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
|
277
MSM8916Pkg/Drivers/ClockDxe/clock_lib2.c
Normal file
277
MSM8916Pkg/Drivers/ClockDxe/clock_lib2.c
Normal 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);
|
||||||
|
}
|
110
MSM8916Pkg/Drivers/ClockDxe/clock_p.h
Normal file
110
MSM8916Pkg/Drivers/ClockDxe/clock_p.h
Normal 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
|
139
MSM8916Pkg/Drivers/ClockDxe/clock_pll.c
Normal file
139
MSM8916Pkg/Drivers/ClockDxe/clock_pll.c
Normal 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;
|
||||||
|
}
|
235
MSM8916Pkg/Include/Chipset/clock-local.h
Normal file
235
MSM8916Pkg/Include/Chipset/clock-local.h
Normal 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
|
81
MSM8916Pkg/Include/Chipset/clock.h
Normal file
81
MSM8916Pkg/Include/Chipset/clock.h
Normal 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
|
223
MSM8916Pkg/Include/Chipset/clock_lib2.h
Normal file
223
MSM8916Pkg/Include/Chipset/clock_lib2.h
Normal 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
|
102
MSM8916Pkg/Include/Chipset/clock_pll.h
Normal file
102
MSM8916Pkg/Include/Chipset/clock_pll.h
Normal 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
|
111
MSM8916Pkg/Include/Library/LKEnvLib.h
Normal file
111
MSM8916Pkg/Include/Library/LKEnvLib.h
Normal 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
|
12
MSM8916Pkg/Include/Library/QcomClockLib.h
Normal file
12
MSM8916Pkg/Include/Library/QcomClockLib.h
Normal 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
|
11
MSM8916Pkg/Include/Library/QcomPlatformClockInitLib.h
Normal file
11
MSM8916Pkg/Include/Library/QcomPlatformClockInitLib.h
Normal 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
|
11
MSM8916Pkg/Include/Library/minstdbool.h
Normal file
11
MSM8916Pkg/Include/Library/minstdbool.h
Normal 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
|
70
MSM8916Pkg/Include/Library/minstdint.h
Normal file
70
MSM8916Pkg/Include/Library/minstdint.h
Normal 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
|
17
MSM8916Pkg/Include/Library/minstring.h
Normal file
17
MSM8916Pkg/Include/Library/minstring.h
Normal 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
|
93
MSM8916Pkg/Include/Platform/clock.h
Normal file
93
MSM8916Pkg/Include/Platform/clock.h
Normal 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
|
286
MSM8916Pkg/Include/Platform/iomap.h
Normal file
286
MSM8916Pkg/Include/Platform/iomap.h
Normal 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
|
68
MSM8916Pkg/Include/Platform/irqs.h
Normal file
68
MSM8916Pkg/Include/Platform/irqs.h
Normal 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 */
|
41
MSM8916Pkg/Include/Protocol/QcomClock.h
Normal file
41
MSM8916Pkg/Include/Protocol/QcomClock.h
Normal 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
|
@ -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
|
||||||
|
|
612
MSM8916Pkg/Library/QcomPlatformClockInitLib/msm8916-clock.c
Normal file
612
MSM8916Pkg/Library/QcomPlatformClockInitLib/msm8916-clock.c
Normal 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;
|
||||||
|
}
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEFIDroidKeypadDeviceProtocolGuid = { 0xb27625b5, 0x0b6c, 0x4614, { 0xaa, 0x3c, 0x33, 0x13, 0xb5, 0x1d, 0x36, 0x46 } }
|
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]
|
[PcdsFixedAtBuild.common]
|
||||||
# Simple FrameBuffer
|
# Simple FrameBuffer
|
||||||
|
@ -72,6 +72,9 @@
|
|||||||
MemoryInitPeiLib|MSM8916Pkg/Library/MemoryInitPeiLib/PeiMemoryAllocationLib.inf
|
MemoryInitPeiLib|MSM8916Pkg/Library/MemoryInitPeiLib/PeiMemoryAllocationLib.inf
|
||||||
PlatformPeiLib|MSM8916Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
|
PlatformPeiLib|MSM8916Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
|
||||||
|
|
||||||
|
# SoC Drivers
|
||||||
|
QcomPlatformClockInitLib|MSM8916Pkg/Library/QcomPlatformClockInitLib/QcomPlatformClockInitLib.inf
|
||||||
|
|
||||||
[LibraryClasses.common.SEC]
|
[LibraryClasses.common.SEC]
|
||||||
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
|
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
|
||||||
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
|
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
|
||||||
@ -79,6 +82,22 @@
|
|||||||
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
|
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
|
||||||
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.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
|
# Pcd Section - list of all EDK II PCD Entries defined by this Platform
|
||||||
@ -180,9 +199,11 @@
|
|||||||
MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
|
MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# GPIO
|
# SoC Drivers
|
||||||
#
|
#
|
||||||
|
|
||||||
|
MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# Virtual Keyboard
|
# Virtual Keyboard
|
||||||
#
|
#
|
||||||
|
@ -153,6 +153,10 @@ READ_LOCK_STATUS = TRUE
|
|||||||
INF MSM8916Pkg/Drivers/MSM8916PkgDxe/MSM8916PkgDxe.inf
|
INF MSM8916Pkg/Drivers/MSM8916PkgDxe/MSM8916PkgDxe.inf
|
||||||
INF MSM8916Pkg/Drivers/SimpleFbDxe/SimpleFbDxe.inf
|
INF MSM8916Pkg/Drivers/SimpleFbDxe/SimpleFbDxe.inf
|
||||||
|
|
||||||
|
#
|
||||||
|
# SoC Drivers
|
||||||
|
#
|
||||||
|
INF MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# USB Host Support
|
# USB Host Support
|
||||||
|
Loading…
Reference in New Issue
Block a user