mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-02-12 02:05:54 +00:00
Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
193 lines
4.2 KiB
C
193 lines
4.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2020 Linaro Ltd
|
|
*/
|
|
|
|
#include <linux/clk.h>
|
|
#include <linux/device.h>
|
|
#include <linux/interconnect-provider.h>
|
|
#include <linux/io.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of_device.h>
|
|
#include <linux/of_platform.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include "smd-rpm.h"
|
|
#include "icc-rpm.h"
|
|
|
|
static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
|
|
{
|
|
struct qcom_icc_provider *qp;
|
|
struct qcom_icc_node *qn;
|
|
struct icc_provider *provider;
|
|
struct icc_node *n;
|
|
u64 sum_bw;
|
|
u64 max_peak_bw;
|
|
u64 rate;
|
|
u32 agg_avg = 0;
|
|
u32 agg_peak = 0;
|
|
int ret, i;
|
|
|
|
qn = src->data;
|
|
provider = src->provider;
|
|
qp = to_qcom_provider(provider);
|
|
|
|
list_for_each_entry(n, &provider->nodes, node_list)
|
|
provider->aggregate(n, 0, n->avg_bw, n->peak_bw,
|
|
&agg_avg, &agg_peak);
|
|
|
|
sum_bw = icc_units_to_bps(agg_avg);
|
|
max_peak_bw = icc_units_to_bps(agg_peak);
|
|
|
|
/* send bandwidth request message to the RPM processor */
|
|
if (qn->mas_rpm_id != -1) {
|
|
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
|
|
RPM_BUS_MASTER_REQ,
|
|
qn->mas_rpm_id,
|
|
sum_bw);
|
|
if (ret) {
|
|
pr_err("qcom_icc_rpm_smd_send mas %d error %d\n",
|
|
qn->mas_rpm_id, ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if (qn->slv_rpm_id != -1) {
|
|
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
|
|
RPM_BUS_SLAVE_REQ,
|
|
qn->slv_rpm_id,
|
|
sum_bw);
|
|
if (ret) {
|
|
pr_err("qcom_icc_rpm_smd_send slv %d error %d\n",
|
|
qn->slv_rpm_id, ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
rate = max(sum_bw, max_peak_bw);
|
|
|
|
do_div(rate, qn->buswidth);
|
|
rate = min_t(u64, rate, LONG_MAX);
|
|
|
|
if (qn->rate == rate)
|
|
return 0;
|
|
|
|
for (i = 0; i < qp->num_clks; i++) {
|
|
ret = clk_set_rate(qp->bus_clks[i].clk, rate);
|
|
if (ret) {
|
|
pr_err("%s clk_set_rate error: %d\n",
|
|
qp->bus_clks[i].id, ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
qn->rate = rate;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int qnoc_probe(struct platform_device *pdev, size_t cd_size, int cd_num,
|
|
const struct clk_bulk_data *cd)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
const struct qcom_icc_desc *desc;
|
|
struct icc_onecell_data *data;
|
|
struct icc_provider *provider;
|
|
struct qcom_icc_node **qnodes;
|
|
struct qcom_icc_provider *qp;
|
|
struct icc_node *node;
|
|
size_t num_nodes, i;
|
|
int ret;
|
|
|
|
/* wait for the RPM proxy */
|
|
if (!qcom_icc_rpm_smd_available())
|
|
return -EPROBE_DEFER;
|
|
|
|
desc = of_device_get_match_data(dev);
|
|
if (!desc)
|
|
return -EINVAL;
|
|
|
|
qnodes = desc->nodes;
|
|
num_nodes = desc->num_nodes;
|
|
|
|
qp = devm_kzalloc(dev, sizeof(*qp), GFP_KERNEL);
|
|
if (!qp)
|
|
return -ENOMEM;
|
|
|
|
data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
|
|
GFP_KERNEL);
|
|
if (!data)
|
|
return -ENOMEM;
|
|
|
|
qp->bus_clks = devm_kmemdup(dev, cd, cd_size,
|
|
GFP_KERNEL);
|
|
if (!qp->bus_clks)
|
|
return -ENOMEM;
|
|
|
|
qp->num_clks = cd_num;
|
|
ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = clk_bulk_prepare_enable(qp->num_clks, qp->bus_clks);
|
|
if (ret)
|
|
return ret;
|
|
|
|
provider = &qp->provider;
|
|
INIT_LIST_HEAD(&provider->nodes);
|
|
provider->dev = dev;
|
|
provider->set = qcom_icc_set;
|
|
provider->aggregate = icc_std_aggregate;
|
|
provider->xlate = of_icc_xlate_onecell;
|
|
provider->data = data;
|
|
|
|
ret = icc_provider_add(provider);
|
|
if (ret) {
|
|
dev_err(dev, "error adding interconnect provider: %d\n", ret);
|
|
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
|
return ret;
|
|
}
|
|
|
|
for (i = 0; i < num_nodes; i++) {
|
|
size_t j;
|
|
|
|
node = icc_node_create(qnodes[i]->id);
|
|
if (IS_ERR(node)) {
|
|
ret = PTR_ERR(node);
|
|
goto err;
|
|
}
|
|
|
|
node->name = qnodes[i]->name;
|
|
node->data = qnodes[i];
|
|
icc_node_add(node, provider);
|
|
|
|
for (j = 0; j < qnodes[i]->num_links; j++)
|
|
icc_link_create(node, qnodes[i]->links[j]);
|
|
|
|
data->nodes[i] = node;
|
|
}
|
|
data->num_nodes = num_nodes;
|
|
|
|
platform_set_drvdata(pdev, qp);
|
|
|
|
return 0;
|
|
err:
|
|
icc_nodes_remove(provider);
|
|
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
|
icc_provider_del(provider);
|
|
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(qnoc_probe);
|
|
|
|
int qnoc_remove(struct platform_device *pdev)
|
|
{
|
|
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
|
|
|
|
icc_nodes_remove(&qp->provider);
|
|
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
|
return icc_provider_del(&qp->provider);
|
|
}
|
|
EXPORT_SYMBOL(qnoc_remove);
|