mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
ddr_bandwidth: support multi-ports config for one channel [1/1]
PD#172256 Problem: ddr bandwidth prot config can only set 1 port for 1 channel. But dmc controller support measure many ports on 1 channel. Solution: Using bit mask to support multi-ports config for one channel. Verify: P212 Change-Id: Iad79e6ebd6aeb74b0e31b3f1bee08de4fd557cc1 Signed-off-by: tao zeng <tao.zeng@amlogic.com>
This commit is contained in:
@@ -40,12 +40,18 @@ static void g12_dmc_port_config(struct ddr_bandwidth *db, int channel, int port)
|
||||
DMC_MON_G12_CTRL6, DMC_MON_G12_CTRL8};
|
||||
int subport = -1;
|
||||
|
||||
/* clear all port mask */
|
||||
if (port < 0) {
|
||||
writel(0, db->ddr_reg + rp[channel]);
|
||||
writel(0, db->ddr_reg + rs[channel]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (port >= PORT_MAJOR)
|
||||
subport = port - PORT_MAJOR;
|
||||
|
||||
if (subport < 0) {
|
||||
val = readl(db->ddr_reg + rp[channel]);
|
||||
val &= ~(0xffffff << 0);
|
||||
val |= (1 << port);
|
||||
writel(val, db->ddr_reg + rp[channel]);
|
||||
val = 0xffff;
|
||||
@@ -54,7 +60,6 @@ static void g12_dmc_port_config(struct ddr_bandwidth *db, int channel, int port)
|
||||
val = (0x1 << 23); /* select device */
|
||||
writel(val, db->ddr_reg + rp[channel]);
|
||||
val = readl(db->ddr_reg + rs[channel]);
|
||||
val &= ~(0xffff);
|
||||
val |= (1 << subport);
|
||||
writel(val, db->ddr_reg + rs[channel]);
|
||||
}
|
||||
@@ -124,7 +129,7 @@ static void g12_dmc_bandwidth_init(struct ddr_bandwidth *db)
|
||||
g12_dmc_bandwidth_enable(db);
|
||||
|
||||
for (i = 0; i < db->channels; i++)
|
||||
g12_dmc_port_config(db, i, db->port[i]);
|
||||
g12_dmc_port_config(db, i, -1);
|
||||
}
|
||||
|
||||
static int g12_handle_irq(struct ddr_bandwidth *db, struct ddr_grant *dg)
|
||||
|
||||
@@ -37,6 +37,12 @@ static void gx_dmc_port_config(struct ddr_bandwidth *db, int channel, int port)
|
||||
unsigned int val;
|
||||
int subport = -1;
|
||||
|
||||
/* set to a unused port to clear bandwidth */
|
||||
if (port < 0) {
|
||||
writel(0x8016ffff, db->ddr_reg + DMC_MON_CTRL2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (port >= PORT_MAJOR)
|
||||
subport = port - PORT_MAJOR;
|
||||
|
||||
@@ -89,7 +95,7 @@ static void gx_dmc_bandwidth_init(struct ddr_bandwidth *db)
|
||||
writel(db->clock_count, db->ddr_reg + DMC_MON_CTRL3);
|
||||
gx_dmc_bandwidth_enable(db);
|
||||
|
||||
gx_dmc_port_config(db, 0, db->port[0]);
|
||||
gx_dmc_port_config(db, 0, -1);
|
||||
}
|
||||
|
||||
static int gx_handle_irq(struct ddr_bandwidth *db, struct ddr_grant *dg)
|
||||
|
||||
@@ -44,9 +44,14 @@ static void gxl_dmc_port_config(struct ddr_bandwidth *db, int channel, int port)
|
||||
if (port >= PORT_MAJOR)
|
||||
subport = port - PORT_MAJOR;
|
||||
|
||||
/* clear all port mask */
|
||||
if (port < 0) {
|
||||
writel(0, db->ddr_reg + port_reg[channel]);
|
||||
return;
|
||||
}
|
||||
|
||||
val = readl(db->ddr_reg + port_reg[channel]);
|
||||
if (port < 16) {
|
||||
val &= ~(0xffff << 16);
|
||||
val |= ((1 << (16 + port)) | 0xffff);
|
||||
} else if (subport > 0) {
|
||||
val &= ~(0xffffffff);
|
||||
@@ -94,7 +99,7 @@ static void gxl_dmc_bandwidth_init(struct ddr_bandwidth *db)
|
||||
gxl_dmc_bandwidth_enable(db);
|
||||
|
||||
for (i = 0; i < db->channels; i++)
|
||||
gxl_dmc_port_config(db, i, db->port[i]);
|
||||
gxl_dmc_port_config(db, i, -1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -133,15 +133,34 @@ static char *find_port_name(int id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int format_port(char *buf, u64 port_mask)
|
||||
{
|
||||
u64 t;
|
||||
int i, size = 0;
|
||||
char *name;
|
||||
|
||||
for (i = 0; i < sizeof(u64) * 8; i++) {
|
||||
t = 1ULL << i;
|
||||
if (port_mask & t) {
|
||||
name = find_port_name(i);
|
||||
if (!name)
|
||||
continue;
|
||||
size += sprintf(buf + size, " %s\n", name);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t ddr_channel_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
int size = 0, i;
|
||||
|
||||
for (i = 0; i < aml_db->channels; i++)
|
||||
size += sprintf(buf + size, "ch %d:%3d, %s\n",
|
||||
i, aml_db->port[i],
|
||||
find_port_name(aml_db->port[i]));
|
||||
for (i = 0; i < aml_db->channels; i++) {
|
||||
size += sprintf(buf + size, "ch %d:%16llx: ports:\n",
|
||||
i, aml_db->port[i]);
|
||||
size += format_port(buf + size, aml_db->port[i]);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
@@ -156,8 +175,8 @@ static ssize_t ddr_channel_store(struct class *cla,
|
||||
return count;
|
||||
}
|
||||
|
||||
if (ch >= MAX_CHANNEL ||
|
||||
(ch && aml_db->cpu_type < MESON_CPU_MAJOR_ID_GXTVBB) ||
|
||||
if (ch >= MAX_CHANNEL || ch < 0 ||
|
||||
aml_db->cpu_type < MESON_CPU_MAJOR_ID_GXTVBB ||
|
||||
port > MAX_PORTS) {
|
||||
pr_info("invalid channel %d or port %d\n", ch, port);
|
||||
return count;
|
||||
@@ -165,7 +184,10 @@ static ssize_t ddr_channel_store(struct class *cla,
|
||||
|
||||
if (aml_db->ops && aml_db->ops->config_port) {
|
||||
aml_db->ops->config_port(aml_db, ch, port);
|
||||
aml_db->port[ch] = port;
|
||||
if (port < 0) /* clear port set */
|
||||
aml_db->port[ch] = 0;
|
||||
else
|
||||
aml_db->port[ch] |= 1ULL << port;
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -226,11 +248,11 @@ static ssize_t mode_store(struct class *cla,
|
||||
|
||||
if (val == MODE_AUTODETECT && aml_db->ops && aml_db->ops->config_port) {
|
||||
if (aml_db->mali_port[0] >= 0) {
|
||||
aml_db->port[0] = aml_db->mali_port[0];
|
||||
aml_db->port[0] = (1ULL << aml_db->mali_port[0]);
|
||||
aml_db->ops->config_port(aml_db, 0, aml_db->port[0]);
|
||||
}
|
||||
if (aml_db->mali_port[1] >= 0) {
|
||||
aml_db->port[1] = aml_db->mali_port[1];
|
||||
aml_db->port[1] = (1ULL << aml_db->mali_port[1]);
|
||||
aml_db->ops->config_port(aml_db, 1, aml_db->port[1]);
|
||||
}
|
||||
}
|
||||
@@ -282,8 +304,8 @@ static ssize_t clock_count_store(struct class *cla,
|
||||
static ssize_t bandwidth_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
size_t s = 0, i;
|
||||
int percent, rem;
|
||||
size_t s = 0;
|
||||
int percent, rem, i;
|
||||
#define BANDWIDTH_PREFIX "Total bandwidth: %8d KB/s, usage: %2d.%02d%%\n"
|
||||
|
||||
if (aml_db->mode != MODE_ENABLE)
|
||||
@@ -295,8 +317,8 @@ static ssize_t bandwidth_show(struct class *cla,
|
||||
aml_db->total_bandwidth, percent, rem);
|
||||
|
||||
for (i = 0; i < aml_db->channels; i++) {
|
||||
s += sprintf(buf + s, "port%d: %8d KB/s\n",
|
||||
aml_db->port[i], aml_db->bandwidth[i]);
|
||||
s += sprintf(buf + s, "ch:%d port bit:%16llx: %8d KB/s\n",
|
||||
i, aml_db->port[i], aml_db->bandwidth[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@@ -592,6 +614,9 @@ static int __ref ddr_bandwidth_probe(struct platform_device *pdev)
|
||||
goto inval;
|
||||
}
|
||||
|
||||
if (!aml_db->ops->config_port)
|
||||
goto inval;
|
||||
|
||||
r = class_register(&aml_ddr_class);
|
||||
if (r)
|
||||
pr_info("%s, class regist failed\n", __func__);
|
||||
|
||||
@@ -130,25 +130,25 @@ struct ddr_bandwidth_ops {
|
||||
};
|
||||
|
||||
struct ddr_bandwidth {
|
||||
void __iomem *ddr_reg;
|
||||
void __iomem *pll_reg;
|
||||
struct class *class;
|
||||
unsigned short cpu_type;
|
||||
unsigned short real_ports;
|
||||
char busy;
|
||||
char mode;
|
||||
int mali_port[2];
|
||||
unsigned int threshold;
|
||||
struct work_struct work_bandwidth;
|
||||
unsigned int irq_num;
|
||||
unsigned int clock_count;
|
||||
unsigned int channels;
|
||||
unsigned int port[MAX_CHANNEL];
|
||||
unsigned int bandwidth[MAX_CHANNEL];
|
||||
unsigned int total_usage;
|
||||
unsigned int total_bandwidth;
|
||||
u64 port[MAX_CHANNEL];
|
||||
void __iomem *ddr_reg;
|
||||
void __iomem *pll_reg;
|
||||
struct class *class;
|
||||
struct ddr_port_desc *port_desc;
|
||||
struct ddr_bandwidth_ops *ops;
|
||||
struct work_struct work_bandwidth;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_DDR_BANDWIDTH
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef __DDR_PORT_DESC_H__
|
||||
#define __DDR_PORT_DESC_H__
|
||||
|
||||
#define MAX_PORTS 256
|
||||
#define MAX_PORTS 63
|
||||
#define MAX_NAME 15
|
||||
#define PORT_MAJOR 32
|
||||
|
||||
|
||||
Reference in New Issue
Block a user