Files
i2som-imx-linux/include/linux/imx_sema4.h
Anson Huang aea226305e ENGR00331269-2 ARM: imx: add A9-M4 clk/power management for i.mx6sx
As A9 and M4 share many resources on i.MX6SX, especially for
clk and power related resource, so we need to handle the hardware
conflict between these two cores, there are two cases that we
need to consider currently:

1. clk management: for every clk node, only when both A9 and
   M4 do NOT need it, then we can disable it from hardware;
2. power management: only when both A9 and M4 agree to enter
   low power mode, then system can enter it.

Here we use MU and hardware SEMA4 to achieve our goal, MU is
for communiation between A9 and M4, SEMA4 is to protect the
shared memory.

For clk management, we use shared memory to maintain the clk
status for both A9 and M4 side, and this shared memory is
protected by hardware SEMA4, A9 and M4 will maintain their
own clk tree info in their SW environment, and get other
CORE's clk tree info from shared memory to decide whether
to perform a hardware setting change when they plan to.

For power management, M4 is treated as a high speed device
in A9 side, M4 is booting up with 227MHz by default, only
when M4 freq drop to below than 24MHz, then A9 is able to
enter low bus mode and low power idle mode. Everytime A9
is trying to adjust bus freq, it will request M4 to stay
at wfi, and once bus freq scaling is done, A9 will send
message to wake up M4 to continue, this is because M4 can
NOT access DDR or other important bus during bus freq scaling.
Whenever M4 wants high bus freq, it can send message to A9 to
increase bus freq, All these communications are done by MU
module.

For further use case implementation, we can define new protocol
to achieve, everytime MU receives a message, it will trigger
a thread to handle this request, A9 can response according
to the message.

Signed-off-by: Anson Huang <b20788@freescale.com>
2017-09-28 19:49:14 -05:00

73 lines
1.8 KiB
C

/*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __LINUX_IMX_SEMA4_H__
#define __LINUX_IMX_SEMA4_H__
/* semaphore number */
#define MCC_SHMEM_SEMAPHORE_NUMBER (1)
#define MCC_PRINTF_SEMAPHORE_NUMBER (2)
#define MCC_I2C_SEMAPHORE_NUMBER (3)
#define MCC_RESERVED1_SEMAPHORE_NUMBER (4)
#define MCC_RESERVED2_SEMAPHORE_NUMBER (5)
#define MCC_POWER_SHMEM_NUMBER (6)
#define SEMA4_NUM_DEVICES 1
#define SEMA4_NUM_GATES 16
#define SEMA4_UNLOCK 0x00
#define SEMA4_A9_LOCK 0x01
#define SEMA4_GATE_MASK 0x03
#define CORE_MUTEX_VALID (('c'<<24)|('m'<<24)|('t'<<24)|'x')
/*
* The enumerates
*/
enum {
/* sema4 registers offset */
SEMA4_CP0INE = 0x40,
SEMA4_CP1INE = 0x48,
SEMA4_CP0NTF = 0x80,
SEMA4_CP1NTF = 0x88,
};
static const unsigned int idx_sema4[16] = {
1 << 7, 1 << 6, 1 << 5, 1 << 4,
1 << 3, 1 << 2, 1 << 1, 1 << 0,
1 << 15, 1 << 14, 1 << 13, 1 << 12,
1 << 11, 1 << 10, 1 << 9, 1 << 8,
};
struct imx_sema4_mutex {
u32 valid;
u32 gate_num;
unsigned char gate_val;
wait_queue_head_t wait_q;
};
struct imx_sema4_mutex_device {
struct device *dev;
u16 cpntf_val;
u16 cpine_val;
void __iomem *ioaddr; /* Mapped address */
spinlock_t lock; /* Mutex */
int irq;
u16 alloced;
struct imx_sema4_mutex *mutex_ptr[16];
};
struct imx_sema4_mutex *
imx_sema4_mutex_create(u32 dev_num, u32 mutex_num);
int imx_sema4_mutex_destroy(struct imx_sema4_mutex *mutex_ptr);
int imx_sema4_mutex_trylock(struct imx_sema4_mutex *mutex_ptr);
int imx_sema4_mutex_lock(struct imx_sema4_mutex *mutex_ptr);
int imx_sema4_mutex_unlock(struct imx_sema4_mutex *mutex_ptr);
#endif /* __LINUX_IMX_SEMA4_H__ */