Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] I.MX8 MU support #40

Open
wants to merge 1 commit into
base: sof-v4.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion hw/adsp/dsp/imx8-mu.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,73 @@ static void mu_write(void *opaque, hwaddr addr,
struct adsp_io_info *info = opaque;
struct adsp_dev *adsp = info->adsp;
struct adsp_reg_space *space = info->space;
struct qemu_io_msg_irq irq;
uint64_t aux;

log_write(adsp->log, space, addr, val, size,
info->region[addr >> 2]);

/* set value via SHM */
/* Interrupt arrived, check src */
info->region[addr >> 2] = val;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is OK to leave the initial comment here ' set value via SHM' because we are actually setting the value of register via SHM. Then move the comment with 'Interrupt arrived' just above the switch.


switch(addr) {
case IMX_MU_xCR:

/* send IRQ to parent */
irq.hdr.type = QEMU_IO_TYPE_IRQ;
irq.hdr.msg = QEMU_IO_MSG_IRQ;
irq.hdr.size = sizeof(irq);
irq.irq = 0;

/* send a new message to host */
if (val & IMX_MU_xCR_GIRn(1)) {
/* activate pending bit on MU Side A */
/* TODO: currently activates pending bit on MU Side B,
* so find a way to write to MU Side A regs
* aux = info->region[IMX_MU_xSR >> 2] & ~0;
* aux |= IMX_MU_xSR_GIPn(0);
* info->region[IMX_MU_xSR >> 2] = aux;
*/
qemu_io_send_msg(&irq.hdr);
}

/* send reply to host */
if (val & IMX_MU_xCR_GIRn(0)) {
/* TODO: currently activates pending bit on MU Side B */
aux = info->region[IMX_MU_xSR >> 2] & ~0;
aux |= IMX_MU_xSR_GIPn(1);
info->region[IMX_MU_xSR >> 2] = aux;
qemu_io_send_msg(&irq.hdr);
}

break;
case IMX_MU_xSR:
break;
default:
break;
}
}

void adsp_imx8_irq_msg(struct adsp_dev *adsp, struct qemu_io_msg *msg)
{
struct adsp_io_info *info = adsp->mu;
uint64_t aux;

aux = info->region[IMX_MU_xCR >> 2];

/* reply arrived from host */
if (aux & IMX_MU_xCR_GIRn(1)) {
/* set pending bit for reply on DSP */
aux = info->region[IMX_MU_xSR >> 2] & ~0;
aux |= IMX_MU_xSR_GIPn(1);
info->region[IMX_MU_xSR >> 2] = aux;
}
else {
/* new message arrived from host, so activate pending bit */
aux = info->region[IMX_MU_xSR >> 2] & ~0;
aux |= IMX_MU_xSR_GIPn(0);
info->region[IMX_MU_xSR >> 2] = aux;
}
}

const MemoryRegionOps imx8_mu_ops = {
Expand All @@ -69,4 +130,5 @@ void adsp_imx8_mu_init(struct adsp_dev *adsp, MemoryRegion *parent,
struct adsp_io_info *info)
{
mu_reset(info);
adsp->mu = info;
}
1 change: 1 addition & 0 deletions hw/adsp/dsp/imx8.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static int bridge_cb(void *data, struct qemu_io_msg *msg)
case QEMU_IO_TYPE_REG:
break;
case QEMU_IO_TYPE_IRQ:
adsp_imx8_irq_msg(adsp, msg);
break;
case QEMU_IO_TYPE_PM:
adsp_pm_msg(adsp, msg);
Expand Down
2 changes: 2 additions & 0 deletions include/hw/adsp/mu.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@
/* General Purpose Interrupt Request */
#define IMX_MU_xCR_GIRn(x) BIT(16 + (3 - (x)))

#define MU_BASE_SIDEA 0x5D280000

#endif
1 change: 1 addition & 0 deletions include/hw/audio/adsp-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct adsp_dev_ops {

struct adsp_dev {

struct adsp_io_info *mu;
struct adsp_io_info *shim;
int shm_idx;

Expand Down