xref: /openbmc/qemu/hw/pci-host/fsl_imx8m_phy.c (revision 09951f5a27a7f8633118c1808cf17e66b30c3c62)
1*fd1deb53SBernhard Beschow /*
2*fd1deb53SBernhard Beschow  * i.MX8 PCIe PHY emulation
3*fd1deb53SBernhard Beschow  *
4*fd1deb53SBernhard Beschow  * Copyright (c) 2025 Bernhard Beschow <shentey@gmail.com>
5*fd1deb53SBernhard Beschow  *
6*fd1deb53SBernhard Beschow  * SPDX-License-Identifier: GPL-2.0-or-later
7*fd1deb53SBernhard Beschow  */
8*fd1deb53SBernhard Beschow 
9*fd1deb53SBernhard Beschow #include "qemu/osdep.h"
10*fd1deb53SBernhard Beschow #include "hw/pci-host/fsl_imx8m_phy.h"
11*fd1deb53SBernhard Beschow #include "hw/resettable.h"
12*fd1deb53SBernhard Beschow #include "migration/vmstate.h"
13*fd1deb53SBernhard Beschow 
14*fd1deb53SBernhard Beschow #define CMN_REG075 0x1d4
15*fd1deb53SBernhard Beschow #define ANA_PLL_LOCK_DONE BIT(1)
16*fd1deb53SBernhard Beschow #define ANA_PLL_AFC_DONE BIT(0)
17*fd1deb53SBernhard Beschow 
fsl_imx8m_pcie_phy_read(void * opaque,hwaddr offset,unsigned size)18*fd1deb53SBernhard Beschow static uint64_t fsl_imx8m_pcie_phy_read(void *opaque, hwaddr offset,
19*fd1deb53SBernhard Beschow                                         unsigned size)
20*fd1deb53SBernhard Beschow {
21*fd1deb53SBernhard Beschow     FslImx8mPciePhyState *s = opaque;
22*fd1deb53SBernhard Beschow 
23*fd1deb53SBernhard Beschow     if (offset == CMN_REG075) {
24*fd1deb53SBernhard Beschow         return s->data[offset] | ANA_PLL_LOCK_DONE | ANA_PLL_AFC_DONE;
25*fd1deb53SBernhard Beschow     }
26*fd1deb53SBernhard Beschow 
27*fd1deb53SBernhard Beschow     return s->data[offset];
28*fd1deb53SBernhard Beschow }
29*fd1deb53SBernhard Beschow 
fsl_imx8m_pcie_phy_write(void * opaque,hwaddr offset,uint64_t value,unsigned size)30*fd1deb53SBernhard Beschow static void fsl_imx8m_pcie_phy_write(void *opaque, hwaddr offset,
31*fd1deb53SBernhard Beschow                                      uint64_t value, unsigned size)
32*fd1deb53SBernhard Beschow {
33*fd1deb53SBernhard Beschow     FslImx8mPciePhyState *s = opaque;
34*fd1deb53SBernhard Beschow 
35*fd1deb53SBernhard Beschow     s->data[offset] = value;
36*fd1deb53SBernhard Beschow }
37*fd1deb53SBernhard Beschow 
38*fd1deb53SBernhard Beschow static const MemoryRegionOps fsl_imx8m_pcie_phy_ops = {
39*fd1deb53SBernhard Beschow     .read = fsl_imx8m_pcie_phy_read,
40*fd1deb53SBernhard Beschow     .write = fsl_imx8m_pcie_phy_write,
41*fd1deb53SBernhard Beschow     .impl = {
42*fd1deb53SBernhard Beschow         .min_access_size = 1,
43*fd1deb53SBernhard Beschow         .max_access_size = 1,
44*fd1deb53SBernhard Beschow     },
45*fd1deb53SBernhard Beschow     .valid = {
46*fd1deb53SBernhard Beschow         .min_access_size = 1,
47*fd1deb53SBernhard Beschow         .max_access_size = 8,
48*fd1deb53SBernhard Beschow     },
49*fd1deb53SBernhard Beschow     .endianness = DEVICE_LITTLE_ENDIAN,
50*fd1deb53SBernhard Beschow };
51*fd1deb53SBernhard Beschow 
fsl_imx8m_pcie_phy_realize(DeviceState * dev,Error ** errp)52*fd1deb53SBernhard Beschow static void fsl_imx8m_pcie_phy_realize(DeviceState *dev, Error **errp)
53*fd1deb53SBernhard Beschow {
54*fd1deb53SBernhard Beschow     FslImx8mPciePhyState *s = FSL_IMX8M_PCIE_PHY(dev);
55*fd1deb53SBernhard Beschow 
56*fd1deb53SBernhard Beschow     memory_region_init_io(&s->iomem, OBJECT(s), &fsl_imx8m_pcie_phy_ops, s,
57*fd1deb53SBernhard Beschow                           TYPE_FSL_IMX8M_PCIE_PHY, ARRAY_SIZE(s->data));
58*fd1deb53SBernhard Beschow     sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
59*fd1deb53SBernhard Beschow }
60*fd1deb53SBernhard Beschow 
fsl_imx8m_pcie_phy_reset_hold(Object * obj,ResetType type)61*fd1deb53SBernhard Beschow static void fsl_imx8m_pcie_phy_reset_hold(Object *obj, ResetType type)
62*fd1deb53SBernhard Beschow {
63*fd1deb53SBernhard Beschow     FslImx8mPciePhyState *s = FSL_IMX8M_PCIE_PHY(obj);
64*fd1deb53SBernhard Beschow 
65*fd1deb53SBernhard Beschow     memset(s->data, 0, sizeof(s->data));
66*fd1deb53SBernhard Beschow }
67*fd1deb53SBernhard Beschow 
68*fd1deb53SBernhard Beschow static const VMStateDescription fsl_imx8m_pcie_phy_vmstate = {
69*fd1deb53SBernhard Beschow     .name = "fsl-imx8m-pcie-phy",
70*fd1deb53SBernhard Beschow     .version_id = 1,
71*fd1deb53SBernhard Beschow     .minimum_version_id = 1,
72*fd1deb53SBernhard Beschow     .fields = (const VMStateField[]) {
73*fd1deb53SBernhard Beschow         VMSTATE_UINT8_ARRAY(data, FslImx8mPciePhyState,
74*fd1deb53SBernhard Beschow                             FSL_IMX8M_PCIE_PHY_DATA_SIZE),
75*fd1deb53SBernhard Beschow         VMSTATE_END_OF_LIST()
76*fd1deb53SBernhard Beschow     }
77*fd1deb53SBernhard Beschow };
78*fd1deb53SBernhard Beschow 
fsl_imx8m_pcie_phy_class_init(ObjectClass * klass,void * data)79*fd1deb53SBernhard Beschow static void fsl_imx8m_pcie_phy_class_init(ObjectClass *klass, void *data)
80*fd1deb53SBernhard Beschow {
81*fd1deb53SBernhard Beschow     DeviceClass *dc = DEVICE_CLASS(klass);
82*fd1deb53SBernhard Beschow     ResettableClass *rc = RESETTABLE_CLASS(klass);
83*fd1deb53SBernhard Beschow 
84*fd1deb53SBernhard Beschow     dc->realize = fsl_imx8m_pcie_phy_realize;
85*fd1deb53SBernhard Beschow     dc->vmsd = &fsl_imx8m_pcie_phy_vmstate;
86*fd1deb53SBernhard Beschow     rc->phases.hold = fsl_imx8m_pcie_phy_reset_hold;
87*fd1deb53SBernhard Beschow }
88*fd1deb53SBernhard Beschow 
89*fd1deb53SBernhard Beschow static const TypeInfo fsl_imx8m_pcie_phy_types[] = {
90*fd1deb53SBernhard Beschow     {
91*fd1deb53SBernhard Beschow         .name = TYPE_FSL_IMX8M_PCIE_PHY,
92*fd1deb53SBernhard Beschow         .parent = TYPE_SYS_BUS_DEVICE,
93*fd1deb53SBernhard Beschow         .instance_size = sizeof(FslImx8mPciePhyState),
94*fd1deb53SBernhard Beschow         .class_init = fsl_imx8m_pcie_phy_class_init,
95*fd1deb53SBernhard Beschow     }
96*fd1deb53SBernhard Beschow };
97*fd1deb53SBernhard Beschow 
98*fd1deb53SBernhard Beschow DEFINE_TYPES(fsl_imx8m_pcie_phy_types)
99