Skip to content

Commit

Permalink
[platform][msm] support platform msm8916
Browse files Browse the repository at this point in the history
basic timer+interrupt+UART support, imported from lk2nd sources
  • Loading branch information
samcday committed Apr 29, 2024
1 parent ab0e1fd commit d213437
Show file tree
Hide file tree
Showing 35 changed files with 4,961 additions and 0 deletions.
207 changes: 207 additions & 0 deletions platform/msm/common/clock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*
* Copyright (c) 2012, 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 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 <stdint.h>
#include <lk/debug.h>
#include <lk/reg.h>
#include <lk/err.h>
#include <limits.h>
#include <clock.h>
#include <string.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(void)
{
return &msm_clk_list;
}
#endif
Loading

0 comments on commit d213437

Please sign in to comment.