189cb0ba4SImre Deak // SPDX-License-Identifier: MIT
289cb0ba4SImre Deak /*
389cb0ba4SImre Deak * Copyright © 2022 Intel Corporation
489cb0ba4SImre Deak */
589cb0ba4SImre Deak
689cb0ba4SImre Deak #include "i915_drv.h"
789cb0ba4SImre Deak #include "i915_reg.h"
889cb0ba4SImre Deak
989cb0ba4SImre Deak #include "intel_de.h"
1089cb0ba4SImre Deak #include "intel_display.h"
1189cb0ba4SImre Deak #include "intel_dkl_phy.h"
12d69813c7SImre Deak #include "intel_dkl_phy_regs.h"
1389cb0ba4SImre Deak
14*bfa010f6SJosé Roberto de Souza /**
15*bfa010f6SJosé Roberto de Souza * intel_dkl_phy_init - initialize Dekel PHY
16*bfa010f6SJosé Roberto de Souza * @i915: i915 device instance
17*bfa010f6SJosé Roberto de Souza */
intel_dkl_phy_init(struct drm_i915_private * i915)18*bfa010f6SJosé Roberto de Souza void intel_dkl_phy_init(struct drm_i915_private *i915)
19*bfa010f6SJosé Roberto de Souza {
20*bfa010f6SJosé Roberto de Souza spin_lock_init(&i915->display.dkl.phy_lock);
21*bfa010f6SJosé Roberto de Souza }
22*bfa010f6SJosé Roberto de Souza
2389cb0ba4SImre Deak static void
dkl_phy_set_hip_idx(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg)24b8ed5533SImre Deak dkl_phy_set_hip_idx(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
2589cb0ba4SImre Deak {
2689cb0ba4SImre Deak enum tc_port tc_port = DKL_REG_TC_PORT(reg);
2789cb0ba4SImre Deak
2889cb0ba4SImre Deak drm_WARN_ON(&i915->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS);
2989cb0ba4SImre Deak
3089cb0ba4SImre Deak intel_de_write(i915,
3189cb0ba4SImre Deak HIP_INDEX_REG(tc_port),
32b8ed5533SImre Deak HIP_INDEX_VAL(tc_port, reg.bank_idx));
3389cb0ba4SImre Deak }
3489cb0ba4SImre Deak
3589cb0ba4SImre Deak /**
3689cb0ba4SImre Deak * intel_dkl_phy_read - read a Dekel PHY register
3789cb0ba4SImre Deak * @i915: i915 device instance
3889cb0ba4SImre Deak * @reg: Dekel PHY register
3989cb0ba4SImre Deak *
4089cb0ba4SImre Deak * Read the @reg Dekel PHY register.
4189cb0ba4SImre Deak *
4289cb0ba4SImre Deak * Returns the read value.
4389cb0ba4SImre Deak */
4489cb0ba4SImre Deak u32
intel_dkl_phy_read(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg)45b8ed5533SImre Deak intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
4689cb0ba4SImre Deak {
4789cb0ba4SImre Deak u32 val;
4889cb0ba4SImre Deak
4989cb0ba4SImre Deak spin_lock(&i915->display.dkl.phy_lock);
5089cb0ba4SImre Deak
51b8ed5533SImre Deak dkl_phy_set_hip_idx(i915, reg);
52b8ed5533SImre Deak val = intel_de_read(i915, DKL_REG_MMIO(reg));
5389cb0ba4SImre Deak
5489cb0ba4SImre Deak spin_unlock(&i915->display.dkl.phy_lock);
5589cb0ba4SImre Deak
5689cb0ba4SImre Deak return val;
5789cb0ba4SImre Deak }
5889cb0ba4SImre Deak
5989cb0ba4SImre Deak /**
6089cb0ba4SImre Deak * intel_dkl_phy_write - write a Dekel PHY register
6189cb0ba4SImre Deak * @i915: i915 device instance
6289cb0ba4SImre Deak * @reg: Dekel PHY register
6389cb0ba4SImre Deak * @val: value to write
6489cb0ba4SImre Deak *
6589cb0ba4SImre Deak * Write @val to the @reg Dekel PHY register.
6689cb0ba4SImre Deak */
6789cb0ba4SImre Deak void
intel_dkl_phy_write(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg,u32 val)68b8ed5533SImre Deak intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val)
6989cb0ba4SImre Deak {
7089cb0ba4SImre Deak spin_lock(&i915->display.dkl.phy_lock);
7189cb0ba4SImre Deak
72b8ed5533SImre Deak dkl_phy_set_hip_idx(i915, reg);
73b8ed5533SImre Deak intel_de_write(i915, DKL_REG_MMIO(reg), val);
7489cb0ba4SImre Deak
7589cb0ba4SImre Deak spin_unlock(&i915->display.dkl.phy_lock);
7689cb0ba4SImre Deak }
7789cb0ba4SImre Deak
7889cb0ba4SImre Deak /**
7989cb0ba4SImre Deak * intel_dkl_phy_rmw - read-modify-write a Dekel PHY register
8089cb0ba4SImre Deak * @i915: i915 device instance
8189cb0ba4SImre Deak * @reg: Dekel PHY register
8289cb0ba4SImre Deak * @clear: mask to clear
8389cb0ba4SImre Deak * @set: mask to set
8489cb0ba4SImre Deak *
8589cb0ba4SImre Deak * Read the @reg Dekel PHY register, clearing then setting the @clear/@set bits in it, and writing
8689cb0ba4SImre Deak * this value back to the register if the value differs from the read one.
8789cb0ba4SImre Deak */
8889cb0ba4SImre Deak void
intel_dkl_phy_rmw(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg,u32 clear,u32 set)89b8ed5533SImre Deak intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set)
9089cb0ba4SImre Deak {
9189cb0ba4SImre Deak spin_lock(&i915->display.dkl.phy_lock);
9289cb0ba4SImre Deak
93b8ed5533SImre Deak dkl_phy_set_hip_idx(i915, reg);
94b8ed5533SImre Deak intel_de_rmw(i915, DKL_REG_MMIO(reg), clear, set);
9589cb0ba4SImre Deak
9689cb0ba4SImre Deak spin_unlock(&i915->display.dkl.phy_lock);
9789cb0ba4SImre Deak }
9889cb0ba4SImre Deak
9989cb0ba4SImre Deak /**
10089cb0ba4SImre Deak * intel_dkl_phy_posting_read - do a posting read from a Dekel PHY register
10189cb0ba4SImre Deak * @i915: i915 device instance
10289cb0ba4SImre Deak * @reg: Dekel PHY register
10389cb0ba4SImre Deak *
10489cb0ba4SImre Deak * Read the @reg Dekel PHY register without returning the read value.
10589cb0ba4SImre Deak */
10689cb0ba4SImre Deak void
intel_dkl_phy_posting_read(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg)107b8ed5533SImre Deak intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
10889cb0ba4SImre Deak {
10989cb0ba4SImre Deak spin_lock(&i915->display.dkl.phy_lock);
11089cb0ba4SImre Deak
111b8ed5533SImre Deak dkl_phy_set_hip_idx(i915, reg);
112b8ed5533SImre Deak intel_de_posting_read(i915, DKL_REG_MMIO(reg));
11389cb0ba4SImre Deak
11489cb0ba4SImre Deak spin_unlock(&i915->display.dkl.phy_lock);
11589cb0ba4SImre Deak }
116