drivers/phy/renesas/r8a779f0-ether-serdes.c
Source file repositories/reference/linux-study-clean/drivers/phy/renesas/r8a779f0-ether-serdes.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/phy/renesas/r8a779f0-ether-serdes.c- Extension
.c- Size
- 14987 bytes
- Lines
- 490
- Domain
- Driver Families
- Bucket
- drivers/phy
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/err.hlinux/iopoll.hlinux/kernel.hlinux/of.hlinux/phy.hlinux/phy/phy.hlinux/platform_device.hlinux/reset.h
Detected Declarations
struct r8a779f0_eth_serdes_drv_datastruct r8a779f0_eth_serdes_channelstruct r8a779f0_eth_serdes_drv_datafunction r8a779f0_eth_serdes_write32function r8a779f0_eth_serdes_read32function r8a779f0_eth_serdes_reg_waitfunction r8a779f0_eth_serdes_common_init_ramfunction r8a779f0_eth_serdes_common_settingfunction r8a779f0_eth_serdes_chan_settingfunction r8a779f0_eth_serdes_chan_speedfunction r8a779f0_eth_serdes_monitor_linkupfunction r8a779f0_eth_serdes_hw_initfunction r8a779f0_eth_serdes_initfunction r8a779f0_eth_serdes_exitfunction r8a779f0_eth_serdes_hw_init_latefunction r8a779f0_eth_serdes_power_onfunction r8a779f0_eth_serdes_set_modefunction r8a779f0_eth_serdes_set_speedfunction r8a779f0_eth_serdes_probefunction r8a779f0_eth_serdes_remove
Annotated Snippet
struct r8a779f0_eth_serdes_channel {
struct r8a779f0_eth_serdes_drv_data *dd;
struct phy *phy;
void __iomem *addr;
phy_interface_t phy_interface;
int speed;
int index;
};
struct r8a779f0_eth_serdes_drv_data {
void __iomem *addr;
struct platform_device *pdev;
struct reset_control *reset;
struct r8a779f0_eth_serdes_channel channel[R8A779F0_ETH_SERDES_NUM];
bool initialized;
};
/*
* The datasheet describes initialization procedure without any information
* about registers' name/bits. So, this is all black magic to initialize
* the hardware.
*/
static void r8a779f0_eth_serdes_write32(void __iomem *addr, u32 offs, u32 bank, u32 data)
{
iowrite32(bank, addr + R8A779F0_ETH_SERDES_BANK_SELECT);
iowrite32(data, addr + offs);
}
static u32 r8a779f0_eth_serdes_read32(void __iomem *addr, u32 offs, u32 bank)
{
iowrite32(bank, addr + R8A779F0_ETH_SERDES_BANK_SELECT);
return ioread32(addr + offs);
}
static int
r8a779f0_eth_serdes_reg_wait(struct r8a779f0_eth_serdes_channel *channel,
u32 offs, u32 bank, u32 mask, u32 expected)
{
int ret;
u32 val;
iowrite32(bank, channel->addr + R8A779F0_ETH_SERDES_BANK_SELECT);
ret = readl_poll_timeout_atomic(channel->addr + offs, val,
(val & mask) == expected,
1, R8A779F0_ETH_SERDES_TIMEOUT_US);
if (ret)
dev_dbg(&channel->phy->dev,
"%s: index %d, offs %x, bank %x, mask %x, expected %x\n",
__func__, channel->index, offs, bank, mask, expected);
return ret;
}
static int
r8a779f0_eth_serdes_common_init_ram(struct r8a779f0_eth_serdes_drv_data *dd)
{
struct r8a779f0_eth_serdes_channel *channel;
int i, ret;
for (i = 0; i < R8A779F0_ETH_SERDES_NUM; i++) {
channel = &dd->channel[i];
ret = r8a779f0_eth_serdes_reg_wait(channel, 0x026c, 0x180, BIT(0), 0x01);
if (ret)
return ret;
}
r8a779f0_eth_serdes_write32(dd->addr, 0x026c, 0x180, 0x03);
return ret;
}
static int
r8a779f0_eth_serdes_common_setting(struct r8a779f0_eth_serdes_channel *channel)
{
struct r8a779f0_eth_serdes_drv_data *dd = channel->dd;
/* Set combination mode */
r8a779f0_eth_serdes_write32(dd->addr, 0x0244, 0x180, 0x00d7);
r8a779f0_eth_serdes_write32(dd->addr, 0x01cc, 0x180, 0xc200);
r8a779f0_eth_serdes_write32(dd->addr, 0x01c4, 0x180, 0x0042);
r8a779f0_eth_serdes_write32(dd->addr, 0x01c8, 0x180, 0x0000);
r8a779f0_eth_serdes_write32(dd->addr, 0x01dc, 0x180, 0x002f);
r8a779f0_eth_serdes_write32(dd->addr, 0x01d0, 0x180, 0x0060);
r8a779f0_eth_serdes_write32(dd->addr, 0x01d8, 0x180, 0x2200);
r8a779f0_eth_serdes_write32(dd->addr, 0x01d4, 0x180, 0x0000);
r8a779f0_eth_serdes_write32(dd->addr, 0x01e0, 0x180, 0x003d);
return 0;
Annotation
- Immediate include surface: `linux/delay.h`, `linux/err.h`, `linux/iopoll.h`, `linux/kernel.h`, `linux/of.h`, `linux/phy.h`, `linux/phy/phy.h`, `linux/platform_device.h`.
- Detected declarations: `struct r8a779f0_eth_serdes_drv_data`, `struct r8a779f0_eth_serdes_channel`, `struct r8a779f0_eth_serdes_drv_data`, `function r8a779f0_eth_serdes_write32`, `function r8a779f0_eth_serdes_read32`, `function r8a779f0_eth_serdes_reg_wait`, `function r8a779f0_eth_serdes_common_init_ram`, `function r8a779f0_eth_serdes_common_setting`, `function r8a779f0_eth_serdes_chan_setting`, `function r8a779f0_eth_serdes_chan_speed`.
- Atlas domain: Driver Families / drivers/phy.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.