Apple SoC RTKit/PMGR updates for 6.3.

This time around we have a PMGR change to allow IRQ-safe usage, RTKit
 crash register dump decoding, and a bunch of RTKit API changes used by
 upcoming drivers.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQSByI3Ki0mXziclZJcd+FPLCI8zYgUCY9kAQwAKCRAd+FPLCI8z
 YhQYAP4km7JfYWsQYKjGSqHounJqgzFnaGFyN3xBmUH3cpyEaQD+IP3vl9PBBWqw
 /rrpVlSwfZ6E1VclFTpaE6/KJPDZwwA=
 =tXq9
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmPg3mQACgkQmmx57+YA
 GNkhQg/+INoPNTCkN3iAOVbcYG9AfluK7tHsYXsr/yBxuSJgehGKWWLBDlloANSJ
 ry7tOxlThT+SIuLTTyVTCw18A38eZmbHmBexSxJQek1BDC6BXsVsnWIV8DCSB461
 9kaVxrFgIjSe1vh+SDgRmQeEvf8qXJRBe8TLm8G2F4Wnf2hxiD5j7Kq0lIj2QC/L
 /ITzB0LE3DbEMvvTdXW2drDzwz1zne0SNolFmPtVo8fDyQbStSURpcR41kzcXodk
 j4PXy0PxGe31eOxkEVyVIo9+bJMGSzLOjgraFBosbfi0n8NfgnPy+NjD5lm2aqz1
 h5zYrFYPqvkwsQMBPsqO3zMk0Q4x/uU0QmSUZfYte3uYMHstEdtG/y+8x6ELUWXr
 /LFtAwYfntj54GbiU1YAP6xXaJpYluCF1ICW10GZTOlprNgSB3rrb3G8HLJChOxb
 /KDtG+O0mVtyS45FZjvBJJ8GAU0FCs17YInUCDQV64XCSa7SV4X7Rw4D/dHrhDL5
 u6yrKlYqLKh/6Nom27a5C7F8L7XIreMu7PK6Hc9lrdQoMBOKd9CQT54G8nEEQHNx
 Hrzk/aXJ5USwREawlDltHnZz2mcXzXCFBhXTJNL/3Tj0qV3QXtP4tHxaW/NFcNaZ
 WX8YpCP0MErPrkvy5VX5H9S3qJKXP6b66pM+rF6c7LoxP9JgURk=
 =HucU
 -----END PGP SIGNATURE-----

Merge tag 'asahi-soc-rtkit-pmgr-6.3' of https://github.com/AsahiLinux/linux into soc/drivers

Apple SoC RTKit/PMGR updates for 6.3.

This time around we have a PMGR change to allow IRQ-safe usage, RTKit
crash register dump decoding, and a bunch of RTKit API changes used by
upcoming drivers.

* tag 'asahi-soc-rtkit-pmgr-6.3' of https://github.com/AsahiLinux/linux:
  soc: apple: rtkit: Add register dump decoding to crashlog
  soc: apple: rtkit: Export non-devm init/free functions
  soc: apple: rtkit: Add a private pointer to apple_rtkit_shmem
  soc: apple: apple-pmgr-pwrstate: Switch to IRQ-safe mode
  soc: apple: rtkit: Add apple_rtkit_idle() function

Link: https://lore.kernel.org/r/4790bdc4-b6e2-228b-771f-023363f65fb3@marcan.st
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2023-02-06 12:02:59 +01:00
commit 7d47f6ffa5
4 changed files with 157 additions and 9 deletions

View file

@ -116,8 +116,9 @@ static int apple_pmgr_ps_power_off(struct generic_pm_domain *genpd)
static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
{
struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
unsigned long flags;
mutex_lock(&ps->genpd.mlock);
spin_lock_irqsave(&ps->genpd.slock, flags);
if (ps->genpd.status == GENPD_STATE_OFF)
dev_err(ps->dev, "PS 0x%x: asserting RESET while powered down\n", ps->offset);
@ -129,7 +130,7 @@ static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned
regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET,
APPLE_PMGR_RESET);
mutex_unlock(&ps->genpd.mlock);
spin_unlock_irqrestore(&ps->genpd.slock, flags);
return 0;
}
@ -137,8 +138,9 @@ static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned
static int apple_pmgr_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
{
struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
unsigned long flags;
mutex_lock(&ps->genpd.mlock);
spin_lock_irqsave(&ps->genpd.slock, flags);
dev_dbg(ps->dev, "PS 0x%x: deassert reset\n", ps->offset);
regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET, 0);
@ -147,7 +149,7 @@ static int apple_pmgr_reset_deassert(struct reset_controller_dev *rcdev, unsigne
if (ps->genpd.status == GENPD_STATE_OFF)
dev_err(ps->dev, "PS 0x%x: RESET was deasserted while powered down\n", ps->offset);
mutex_unlock(&ps->genpd.mlock);
spin_unlock_irqrestore(&ps->genpd.slock, flags);
return 0;
}
@ -222,6 +224,7 @@ static int apple_pmgr_ps_probe(struct platform_device *pdev)
return ret;
}
ps->genpd.flags |= GENPD_FLAG_IRQ_SAFE;
ps->genpd.name = name;
ps->genpd.power_on = apple_pmgr_ps_power_on;
ps->genpd.power_off = apple_pmgr_ps_power_off;

View file

@ -13,6 +13,17 @@
#define APPLE_RTKIT_CRASHLOG_VERSION FOURCC('C', 'v', 'e', 'r')
#define APPLE_RTKIT_CRASHLOG_MBOX FOURCC('C', 'm', 'b', 'x')
#define APPLE_RTKIT_CRASHLOG_TIME FOURCC('C', 't', 'i', 'm')
#define APPLE_RTKIT_CRASHLOG_REGS FOURCC('C', 'r', 'g', '8')
/* For COMPILE_TEST on non-ARM64 architectures */
#ifndef PSR_MODE_EL0t
#define PSR_MODE_EL0t 0x00000000
#define PSR_MODE_EL1t 0x00000004
#define PSR_MODE_EL1h 0x00000005
#define PSR_MODE_EL2t 0x00000008
#define PSR_MODE_EL2h 0x00000009
#define PSR_MODE_MASK 0x0000000f
#endif
struct apple_rtkit_crashlog_header {
u32 fourcc;
@ -31,6 +42,24 @@ struct apple_rtkit_crashlog_mbox_entry {
};
static_assert(sizeof(struct apple_rtkit_crashlog_mbox_entry) == 0x18);
struct apple_rtkit_crashlog_regs {
u32 unk_0;
u32 unk_4;
u64 regs[31];
u64 sp;
u64 pc;
u64 psr;
u64 cpacr;
u64 fpsr;
u64 fpcr;
u64 unk[64];
u64 far;
u64 unk_X;
u64 esr;
u64 unk_Z;
};
static_assert(sizeof(struct apple_rtkit_crashlog_regs) == 0x350);
static void apple_rtkit_crashlog_dump_str(struct apple_rtkit *rtk, u8 *bfr,
size_t size)
{
@ -94,6 +123,66 @@ static void apple_rtkit_crashlog_dump_mailbox(struct apple_rtkit *rtk, u8 *bfr,
}
}
static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr,
size_t size)
{
struct apple_rtkit_crashlog_regs regs;
const char *el;
int i;
if (size < sizeof(regs)) {
dev_warn(rtk->dev, "RTKit: Regs section too small: 0x%zx", size);
return;
}
memcpy(&regs, bfr, sizeof(regs));
switch (regs.psr & PSR_MODE_MASK) {
case PSR_MODE_EL0t:
el = "EL0t";
break;
case PSR_MODE_EL1t:
el = "EL1t";
break;
case PSR_MODE_EL1h:
el = "EL1h";
break;
case PSR_MODE_EL2t:
el = "EL2t";
break;
case PSR_MODE_EL2h:
el = "EL2h";
break;
default:
el = "unknown";
break;
}
dev_warn(rtk->dev, "RTKit: Exception dump:");
dev_warn(rtk->dev, " == Exception taken from %s ==", el);
dev_warn(rtk->dev, " PSR = 0x%llx", regs.psr);
dev_warn(rtk->dev, " PC = 0x%llx\n", regs.pc);
dev_warn(rtk->dev, " ESR = 0x%llx\n", regs.esr);
dev_warn(rtk->dev, " FAR = 0x%llx\n", regs.far);
dev_warn(rtk->dev, " SP = 0x%llx\n", regs.sp);
dev_warn(rtk->dev, "\n");
for (i = 0; i < 31; i += 4) {
if (i < 28)
dev_warn(rtk->dev,
" x%02d-x%02d = %016llx %016llx %016llx %016llx\n",
i, i + 3,
regs.regs[i], regs.regs[i + 1],
regs.regs[i + 2], regs.regs[i + 3]);
else
dev_warn(rtk->dev,
" x%02d-x%02d = %016llx %016llx %016llx\n", i, i + 3,
regs.regs[i], regs.regs[i + 1], regs.regs[i + 2]);
}
dev_warn(rtk->dev, "\n");
}
void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size)
{
size_t offset;
@ -140,6 +229,10 @@ void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size)
apple_rtkit_crashlog_dump_time(rtk, bfr + offset + 16,
section_size);
break;
case APPLE_RTKIT_CRASHLOG_REGS:
apple_rtkit_crashlog_dump_regs(rtk, bfr + offset + 16,
section_size);
break;
default:
dev_warn(rtk->dev,
"RTKit: Unknown crashlog section: %x",

View file

@ -9,6 +9,7 @@
enum {
APPLE_RTKIT_PWR_STATE_OFF = 0x00, /* power off, cannot be restarted */
APPLE_RTKIT_PWR_STATE_SLEEP = 0x01, /* sleeping, can be restarted */
APPLE_RTKIT_PWR_STATE_IDLE = 0x201, /* sleeping, retain state */
APPLE_RTKIT_PWR_STATE_QUIESCED = 0x10, /* running but no communication */
APPLE_RTKIT_PWR_STATE_ON = 0x20, /* normal operating state */
};
@ -698,7 +699,7 @@ static int apple_rtkit_request_mbox_chan(struct apple_rtkit *rtk)
return 0;
}
static struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
const char *mbox_name, int mbox_idx,
const struct apple_rtkit_ops *ops)
{
@ -750,6 +751,7 @@ static struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
kfree(rtk);
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(apple_rtkit_init);
static int apple_rtkit_wait_for_completion(struct completion *c)
{
@ -881,6 +883,26 @@ int apple_rtkit_shutdown(struct apple_rtkit *rtk)
}
EXPORT_SYMBOL_GPL(apple_rtkit_shutdown);
int apple_rtkit_idle(struct apple_rtkit *rtk)
{
int ret;
/* if OFF is used here the co-processor will not wake up again */
ret = apple_rtkit_set_ap_power_state(rtk,
APPLE_RTKIT_PWR_STATE_IDLE);
if (ret)
return ret;
ret = apple_rtkit_set_iop_power_state(rtk, APPLE_RTKIT_PWR_STATE_IDLE);
if (ret)
return ret;
rtk->iop_power_state = APPLE_RTKIT_PWR_STATE_IDLE;
rtk->ap_power_state = APPLE_RTKIT_PWR_STATE_IDLE;
return 0;
}
EXPORT_SYMBOL_GPL(apple_rtkit_idle);
int apple_rtkit_quiesce(struct apple_rtkit *rtk)
{
int ret;
@ -926,10 +948,8 @@ int apple_rtkit_wake(struct apple_rtkit *rtk)
}
EXPORT_SYMBOL_GPL(apple_rtkit_wake);
static void apple_rtkit_free(void *data)
void apple_rtkit_free(struct apple_rtkit *rtk)
{
struct apple_rtkit *rtk = data;
mbox_free_channel(rtk->mbox_chan);
destroy_workqueue(rtk->wq);
@ -940,6 +960,12 @@ static void apple_rtkit_free(void *data)
kfree(rtk->syslog_msg_buffer);
kfree(rtk);
}
EXPORT_SYMBOL_GPL(apple_rtkit_free);
static void apple_rtkit_free_wrapper(void *data)
{
apple_rtkit_free(data);
}
struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
const char *mbox_name, int mbox_idx,
@ -952,7 +978,7 @@ struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
if (IS_ERR(rtk))
return rtk;
ret = devm_add_action_or_reset(dev, apple_rtkit_free, rtk);
ret = devm_add_action_or_reset(dev, apple_rtkit_free_wrapper, rtk);
if (ret)
return ERR_PTR(ret);

View file

@ -22,6 +22,7 @@
* @size: Size of the shared memory buffer.
* @iova: Device VA of shared memory buffer.
* @is_mapped: Shared memory buffer is managed by the co-processor.
* @private: Private data pointer for the parent driver.
*/
struct apple_rtkit_shmem {
@ -30,6 +31,7 @@ struct apple_rtkit_shmem {
size_t size;
dma_addr_t iova;
bool is_mapped;
void *private;
};
/*
@ -77,6 +79,25 @@ struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
const char *mbox_name, int mbox_idx,
const struct apple_rtkit_ops *ops);
/*
* Non-devm version of devm_apple_rtkit_init. Must be freed with
* apple_rtkit_free.
*
* @dev: Pointer to the device node this coprocessor is assocated with
* @cookie: opaque cookie passed to all functions defined in rtkit_ops
* @mbox_name: mailbox name used to communicate with the co-processor
* @mbox_idx: mailbox index to be used if mbox_name is NULL
* @ops: pointer to rtkit_ops to be used for this co-processor
*/
struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
const char *mbox_name, int mbox_idx,
const struct apple_rtkit_ops *ops);
/*
* Free an instance of apple_rtkit.
*/
void apple_rtkit_free(struct apple_rtkit *rtk);
/*
* Reinitialize internal structures. Must only be called with the co-processor
* is held in reset.
@ -104,6 +125,11 @@ int apple_rtkit_wake(struct apple_rtkit *rtk);
*/
int apple_rtkit_shutdown(struct apple_rtkit *rtk);
/*
* Put the co-processor into idle mode
*/
int apple_rtkit_idle(struct apple_rtkit *rtk);
/*
* Checks if RTKit is running and ready to handle messages.
*/