mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
Merge commit '92379ecd7d8c986e65b4f49a41de98ae7b8a27c5'
* commit '92379ecd7d8c986e65b4f49a41de98ae7b8a27c5':
drm/rockchip: remove unused psr_list{,_lock}
soc: rockchip: pm_debug: Add gpio debug info
ARM: dts: rockchip: rk3502-evb1: Update io to save suspend power
video: rockchip: rga3: support iova equal to 0
soc: rockchip: add /proc/rk_zoneinfo/zoneinfo
Change-Id: Ie26a075ccb85ad02a22e05724cf34a58ee5ff850
This commit is contained in:
@@ -414,13 +414,19 @@
|
||||
#define GPIO0_IOC_GPIO0A_PULL_REG 0xff950200
|
||||
#define GPIO0_IOC_GPIO0B_PULL_REG 0xff950204
|
||||
#define GPIO0_IOC_GPIO0C_PULL_REG 0xff950208
|
||||
#define IOC0_GPIO0C5_SMT_REG 0xff950408
|
||||
|
||||
#define GPIO0A02_PULL_Z 0x00330000
|
||||
#define GPIO0A3_PULL_DOWN 0x00c00080
|
||||
#define GPIO0B0_PULL_DOWN 0x00030002
|
||||
#define GPIO0C5_PULL_DOWN 0x0c000800
|
||||
#define GPIO0C5_PULL_Z 0x0c000000
|
||||
#define GPIO0C5_SMT_DISABLE 0x00200000
|
||||
|
||||
/* Note: support max 16 pairs */
|
||||
rockchip,sleep-io-config = <
|
||||
GPIO0_IOC_GPIO0C_PULL_REG GPIO0C5_PULL_DOWN /* PWM0_CH0_CPU */
|
||||
GPIO0_IOC_GPIO0C_PULL_REG GPIO0C5_PULL_Z /* PWM0_CH0_CPU */
|
||||
IOC0_GPIO0C5_SMT_REG GPIO0C5_SMT_DISABLE /* PWM0_CH0_CPU */
|
||||
GPIO0_IOC_GPIO0A_PULL_REG GPIO0A02_PULL_Z /* PWRCTRL0, PWRCTRL1 */
|
||||
GPIO0_IOC_GPIO0A_PULL_REG GPIO0A3_PULL_DOWN /* PWM0_CH2_LCD_BL */
|
||||
GPIO0_IOC_GPIO0B_PULL_REG GPIO0B0_PULL_DOWN /* SAI1_MCLK */
|
||||
>;
|
||||
|
||||
@@ -1920,8 +1920,6 @@ static int rockchip_drm_bind(struct device *dev)
|
||||
|
||||
drm_dev->dev_private = private;
|
||||
|
||||
INIT_LIST_HEAD(&private->psr_list);
|
||||
mutex_init(&private->psr_list_lock);
|
||||
mutex_init(&private->commit_lock);
|
||||
|
||||
private->hdmi_pll.pll = devm_clk_get_optional(dev, "hdmi-tmds-pll");
|
||||
|
||||
@@ -554,8 +554,6 @@ struct rockchip_drm_private {
|
||||
struct gen_pool *secure_buffer_pool;
|
||||
struct mutex mm_lock;
|
||||
struct drm_mm mm;
|
||||
struct list_head psr_list;
|
||||
struct mutex psr_list_lock;
|
||||
struct mutex commit_lock;
|
||||
|
||||
/* private crtc prop */
|
||||
|
||||
@@ -190,6 +190,12 @@ config ROCKCHIP_SUSPEND_MODE
|
||||
help
|
||||
Say Y here if you want to set the suspend mode to the ATF.
|
||||
|
||||
config ROCKCHIP_SUSPEND_DEBUG
|
||||
bool "Rockchip suspend debug"
|
||||
depends on ROCKCHIP_SUSPEND_MODE
|
||||
help
|
||||
Say y here to enable rockchip suspend debug support.
|
||||
|
||||
config ROCKCHIP_SYSTEM_MONITOR
|
||||
tristate "Rockchip system monitor support"
|
||||
help
|
||||
@@ -348,6 +354,12 @@ config RK_MEMBLOCK_PROCFS
|
||||
Extend memblock procfs to show size of each memblock, and shows the
|
||||
result of total size by KiB format.
|
||||
|
||||
config RK_ZONEINFO_PROCFS
|
||||
bool "Zoneinfo procfs support"
|
||||
depends on PROC_FS
|
||||
help
|
||||
Dump all zone information.
|
||||
|
||||
source "drivers/soc/rockchip/minidump/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -24,6 +24,7 @@ obj-$(CONFIG_ROCKCHIP_OPP) += rockchip_opp_select.o
|
||||
obj-$(CONFIG_ROCKCHIP_PERFORMANCE) += rockchip_performance.o
|
||||
obj-$(CONFIG_ROCKCHIP_PVTM) += rockchip_pvtm.o
|
||||
obj-$(CONFIG_ROCKCHIP_RAMDISK) += rockchip_ramdisk.o
|
||||
obj-$(CONFIG_ROCKCHIP_SUSPEND_DEBUG) += rockchip_pm_debug.o
|
||||
obj-$(CONFIG_ROCKCHIP_SUSPEND_MODE) += rockchip_pm_config.o
|
||||
obj-$(CONFIG_ROCKCHIP_SYSTEM_MONITOR) += rockchip_system_monitor.o
|
||||
obj-$(CONFIG_ROCKCHIP_THUNDER_BOOT_MMC) += rockchip_thunderboot_mmc.o
|
||||
@@ -34,4 +35,5 @@ obj-$(CONFIG_ROCKCHIP_NPOR_POWERGOOD) += rockchip_npor_powergood.o
|
||||
obj-$(CONFIG_RK_CMA_PROCFS) += rk_cma_procfs.o
|
||||
obj-$(CONFIG_RK_DMABUF_PROCFS) += rk_dmabuf_procfs.o
|
||||
obj-$(CONFIG_RK_MEMBLOCK_PROCFS) += rk_memblock_procfs.o
|
||||
obj-$(CONFIG_RK_ZONEINFO_PROCFS) += rk_zoneinfo_procfs.o
|
||||
obj-$(CONFIG_ROCKCHIP_MINIDUMP) += minidump/
|
||||
|
||||
137
drivers/soc/rockchip/rk_zoneinfo_procfs.c
Normal file
137
drivers/soc/rockchip/rk_zoneinfo_procfs.c
Normal file
@@ -0,0 +1,137 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2025 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/mmzone.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/page-flags.h>
|
||||
#include <linux/pfn.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
/*
|
||||
* This kernel module creates a procfs entry that prints
|
||||
* detailed zone and page information, including the page's order if it
|
||||
* is part of the buddy allocator (PageBuddy is set). It is updated for
|
||||
* for_each_populated_zone(zone) iterates over all zones
|
||||
* without referencing pgdat. For each zone and order, it shows:
|
||||
* - free_area info by migrate type
|
||||
* - each page in the free list, including:
|
||||
* * page pointer
|
||||
* * PFN (page frame number)
|
||||
* * raw page flags
|
||||
* * physical address
|
||||
* * node ID
|
||||
* * whether it's a compound page
|
||||
* * the (buddy) order if PageBuddy is set
|
||||
*
|
||||
* Usage:
|
||||
* cat /proc/rk_zoneinfo/zoneinfo > /data/data/1.txt
|
||||
*/
|
||||
|
||||
static int rk_zoneinfo_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct zone *zone;
|
||||
int order, type;
|
||||
unsigned long flags;
|
||||
|
||||
seq_puts(m, "==== ZONE & PAGE INFO (with page order) ====\n");
|
||||
|
||||
for_each_populated_zone(zone) {
|
||||
seq_printf(m, "Zone: %s\n", zone->name);
|
||||
seq_printf(m, " managed_pages: %lu\n",
|
||||
atomic_long_read(&zone->managed_pages));
|
||||
seq_printf(m, " spanned_pages: %lu\n", zone->spanned_pages);
|
||||
seq_printf(m, " present_pages: %lu\n\n", zone->present_pages);
|
||||
|
||||
spin_lock_irqsave(&zone->lock, flags);
|
||||
|
||||
/* For each order in this zone, we examine the free lists */
|
||||
for (order = 0; order < MAX_ORDER; order++) {
|
||||
seq_printf(m, "\tOrder: %d | nr_free: %lu\n",
|
||||
order, zone->free_area[order].nr_free);
|
||||
|
||||
for (type = 0; type < MIGRATE_TYPES; type++) {
|
||||
struct list_head *head =
|
||||
&zone->free_area[order].free_list[type];
|
||||
struct page *page;
|
||||
|
||||
if (list_empty(head)) {
|
||||
seq_printf(m, "\t\tMigrate type %d => (empty)\n", type);
|
||||
continue;
|
||||
}
|
||||
|
||||
list_for_each_entry(page, head, lru) {
|
||||
unsigned long pfn = page_to_pfn(page);
|
||||
unsigned int buddy_order = 0;
|
||||
|
||||
if (PageBuddy(page))
|
||||
buddy_order = page_private(page);
|
||||
|
||||
seq_printf(
|
||||
m,
|
||||
"\t\tMigrate type %d => page: %p | PFN: %08lu | phys_addr: 0x%010lx | flags: 0x%lx | compound: %d | node: %d | zone: %s | buddy_order: %u\n",
|
||||
type,
|
||||
page,
|
||||
pfn,
|
||||
(unsigned long)page_to_phys(page),
|
||||
page->flags,
|
||||
PageCompound(page),
|
||||
page_to_nid(page),
|
||||
zone->name,
|
||||
buddy_order
|
||||
);
|
||||
}
|
||||
}
|
||||
seq_puts(m, "\n");
|
||||
}
|
||||
spin_unlock_irqrestore(&zone->lock, flags);
|
||||
seq_puts(m, "----------------------------------------\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk_zoneinfo_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, rk_zoneinfo_show, NULL);
|
||||
}
|
||||
|
||||
static const struct proc_ops rk_zoneinfo_proc_fops = {
|
||||
.proc_open = rk_zoneinfo_proc_open,
|
||||
.proc_read = seq_read,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_release = single_release,
|
||||
};
|
||||
|
||||
static int __init rk_zoneinfo_procfs_init(void)
|
||||
{
|
||||
struct proc_dir_entry *entry;
|
||||
|
||||
entry = proc_mkdir("rk_zoneinfo", NULL);
|
||||
if (!entry)
|
||||
return -ENOENT;
|
||||
|
||||
if (!proc_create("zoneinfo", 0444, entry, &rk_zoneinfo_proc_fops))
|
||||
goto err;
|
||||
|
||||
pr_info("rk_zoneinfo_procfs module loaded.\n");
|
||||
|
||||
return 0;
|
||||
err:
|
||||
remove_proc_subtree("rk_zoneinfo", NULL);
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
module_init(rk_zoneinfo_procfs_init);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("xxm@rock-chips.com");
|
||||
MODULE_DESCRIPTION("iterating zones to show zone/page info and page order if buddy.");
|
||||
125
drivers/soc/rockchip/rockchip_pm_debug.c
Normal file
125
drivers/soc/rockchip/rockchip_pm_debug.c
Normal file
@@ -0,0 +1,125 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Rockchip Power Management Debug Support.
|
||||
*
|
||||
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rockchip/cpu.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
#define RK_IOC_CFG(NAME, REG, LEN, ID, TABLE) \
|
||||
{ \
|
||||
.name = NAME, \
|
||||
.reg_base = REG, \
|
||||
.len = LEN, \
|
||||
.bank_id = ID, \
|
||||
.table = TABLE, \
|
||||
}
|
||||
|
||||
struct rk_gpio_table {
|
||||
u32 offset;
|
||||
u32 len;
|
||||
};
|
||||
|
||||
struct rk_gpio_chip {
|
||||
char *name;
|
||||
u32 reg_base;
|
||||
u32 len;
|
||||
int bank_id;
|
||||
const struct rk_gpio_table *table;
|
||||
};
|
||||
|
||||
static const struct rk_gpio_table rk3506_gpio_table[] = {
|
||||
{ .offset = 0, .len = 0x20,},
|
||||
{ .offset = 0x100, .len = 0x40,},
|
||||
{ .offset = 0x200, .len = 0x10,},
|
||||
{ .offset = 0x300, .len = 0x10,},
|
||||
{ .offset = 0x400, .len = 0x10,},
|
||||
{ .offset = 0x500, .len = 0x10,},
|
||||
{ .offset = 0x600, .len = 0x10,},
|
||||
{ },
|
||||
};
|
||||
|
||||
static const struct rk_gpio_chip rk3506_table[] = {
|
||||
RK_IOC_CFG("gpio0_ioc", 0xff950000, 0x510, 0, rk3506_gpio_table),
|
||||
RK_IOC_CFG("gpio1_ioc", 0xff660000, 0x510, 1, rk3506_gpio_table),
|
||||
RK_IOC_CFG("gpio2_ioc", 0xff4d8000, 0x510, 2, rk3506_gpio_table),
|
||||
RK_IOC_CFG("gpio3_ioc", 0xff4d8000, 0x510, 3, rk3506_gpio_table),
|
||||
{ .name = "gpio4_ioc", .reg_base = 0xff4d8840, .len = 0x10},
|
||||
{ .name = "rm_io", .reg_base = 0xff910080, .len = 0x80},
|
||||
{ .name = "gpio0", .reg_base = 0xff940000, .len = 0x80},
|
||||
{ .name = "gpio1", .reg_base = 0xff870000, .len = 0x80},
|
||||
{ .name = "gpio2", .reg_base = 0xff1c0000, .len = 0x80},
|
||||
{ .name = "gpio3", .reg_base = 0xff1d0000, .len = 0x80},
|
||||
{ .name = "gpio4", .reg_base = 0xff1e0000, .len = 0x80},
|
||||
{ },
|
||||
};
|
||||
|
||||
static const struct rk_gpio_chip *chip_table;
|
||||
|
||||
static void rk_gpio_dump(const struct rk_gpio_chip *chip)
|
||||
{
|
||||
const struct rk_gpio_table *table = chip->table;
|
||||
void __iomem *reg = ioremap(chip->reg_base, chip->len);
|
||||
char prefix[16];
|
||||
int cnt, end;
|
||||
|
||||
if (!reg) {
|
||||
pr_err("Failed to map registers\n");
|
||||
return;
|
||||
}
|
||||
pr_info("%s:\n", chip->name);
|
||||
|
||||
if (!table) {
|
||||
for (cnt = 0; cnt < chip->len; cnt += 0x10) {
|
||||
sprintf(prefix, "%08x: ", chip->reg_base + cnt);
|
||||
print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16,
|
||||
4, (u8 *)reg + cnt, 16, false);
|
||||
}
|
||||
}
|
||||
|
||||
for (; table && table->len; table++) {
|
||||
cnt = table->offset + table->len * chip->bank_id;
|
||||
end = cnt + table->len;
|
||||
for (; cnt < end; cnt += 0x10) {
|
||||
sprintf(prefix, "%08x: ", chip->reg_base + cnt);
|
||||
print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16,
|
||||
4, (u8 *)reg + cnt, 16, false);
|
||||
}
|
||||
|
||||
}
|
||||
iounmap(reg);
|
||||
}
|
||||
|
||||
static int rockchip_pm_syscore_suspend(void)
|
||||
{
|
||||
for (; chip_table && chip_table->name; chip_table++)
|
||||
rk_gpio_dump(chip_table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct syscore_ops rockchip_pm_syscore_ops = {
|
||||
.suspend = rockchip_pm_syscore_suspend,
|
||||
};
|
||||
|
||||
static int __init rockchip_pm_syscore_init(void)
|
||||
{
|
||||
if (of_machine_is_compatible("rockchip,rk3502") ||
|
||||
of_machine_is_compatible("rockchip,rk3506"))
|
||||
chip_table = rk3506_table;
|
||||
|
||||
if (chip_table)
|
||||
register_syscore_ops(&rockchip_pm_syscore_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
late_initcall(rockchip_pm_syscore_init);
|
||||
MODULE_DESCRIPTION("Rockchip pm debug");
|
||||
MODULE_AUTHOR("Rockchip, Inc.");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1409,12 +1409,15 @@ static int rga_mm_get_buffer_info(struct rga_job *job,
|
||||
|
||||
switch (job->scheduler->data->mmu) {
|
||||
case RGA_IOMMU:
|
||||
addr = rga_mm_lookup_iova(internal_buffer);
|
||||
if (addr == 0) {
|
||||
rga_job_err(job, "core[%d] lookup buffer_type[0x%x] iova error!\n",
|
||||
job->core, internal_buffer->type);
|
||||
if (rga_mm_is_invalid_dma_buffer(internal_buffer->dma_buffer)) {
|
||||
rga_job_err(job,
|
||||
"core[%d] handle[%d] lookup buffer_type[0x%x] iova error!\n",
|
||||
job->core, internal_buffer->handle, internal_buffer->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
addr = rga_mm_lookup_iova(internal_buffer);
|
||||
|
||||
break;
|
||||
case RGA_MMU:
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user