Skip to content

Commit 013af22

Browse files
superna9999felipebalbi
authored andcommitted
usb: dwc3: meson-g12a: handle the phy and glue registers separately
On the Amlogic GXL/GXM SoCs, only the USB control registers are available, the PHY mode being handled in the PHY registers. Thus, handle the PHY mode registers in separate regmaps and prepare support for Amlogic GXL/GXM SoCs by moving the regmap setup in a callback set in the SoC match data. Reviewed-by: Martin Blumenstingl <[email protected]> Signed-off-by: Neil Armstrong <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent 5174564 commit 013af22

File tree

1 file changed

+85
-39
lines changed

1 file changed

+85
-39
lines changed

drivers/usb/dwc3/dwc3-meson-g12a.c

Lines changed: 85 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include <linux/usb/role.h>
3131
#include <linux/regulator/consumer.h>
3232

33-
/* USB2 Ports Control Registers */
33+
/* USB2 Ports Control Registers, offsets are per-port */
3434

3535
#define U2P_REG_SIZE 0x20
3636

@@ -50,14 +50,16 @@
5050

5151
/* USB Glue Control Registers */
5252

53-
#define USB_R0 0x80
53+
#define G12A_GLUE_OFFSET 0x80
54+
55+
#define USB_R0 0x00
5456
#define USB_R0_P30_LANE0_TX2RX_LOOPBACK BIT(17)
5557
#define USB_R0_P30_LANE0_EXT_PCLK_REQ BIT(18)
5658
#define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK GENMASK(28, 19)
5759
#define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK GENMASK(30, 29)
5860
#define USB_R0_U2D_ACT BIT(31)
5961

60-
#define USB_R1 0x84
62+
#define USB_R1 0x04
6163
#define USB_R1_U3H_BIGENDIAN_GS BIT(0)
6264
#define USB_R1_U3H_PME_ENABLE BIT(1)
6365
#define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK GENMASK(4, 2)
@@ -69,23 +71,23 @@
6971
#define USB_R1_U3H_FLADJ_30MHZ_REG_MASK GENMASK(24, 19)
7072
#define USB_R1_P30_PCS_TX_SWING_FULL_MASK GENMASK(31, 25)
7173

72-
#define USB_R2 0x88
74+
#define USB_R2 0x08
7375
#define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(25, 20)
7476
#define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK GENMASK(31, 26)
7577

76-
#define USB_R3 0x8c
78+
#define USB_R3 0x0c
7779
#define USB_R3_P30_SSC_ENABLE BIT(0)
7880
#define USB_R3_P30_SSC_RANGE_MASK GENMASK(3, 1)
7981
#define USB_R3_P30_SSC_REF_CLK_SEL_MASK GENMASK(12, 4)
8082
#define USB_R3_P30_REF_SSP_EN BIT(13)
8183

82-
#define USB_R4 0x90
84+
#define USB_R4 0x10
8385
#define USB_R4_P21_PORT_RESET_0 BIT(0)
8486
#define USB_R4_P21_SLEEP_M0 BIT(1)
8587
#define USB_R4_MEM_PD_MASK GENMASK(3, 2)
8688
#define USB_R4_P21_ONLY BIT(4)
8789

88-
#define USB_R5 0x94
90+
#define USB_R5 0x14
8991
#define USB_R5_ID_DIG_SYNC BIT(0)
9092
#define USB_R5_ID_DIG_REG BIT(1)
9193
#define USB_R5_ID_DIG_CFG_MASK GENMASK(3, 2)
@@ -125,20 +127,27 @@ static const char *meson_a1_phy_names[] = {
125127
"usb2-phy0", "usb2-phy1"
126128
};
127129

130+
struct dwc3_meson_g12a;
131+
128132
struct dwc3_meson_g12a_drvdata {
129133
bool otg_switch_supported;
130134
struct clk_bulk_data *clks;
131135
int num_clks;
132136
const char **phy_names;
133137
int num_phys;
138+
int (*setup_regmaps)(struct dwc3_meson_g12a *priv, void __iomem *base);
134139
};
135140

141+
static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
142+
void __iomem *base);
143+
136144
static struct dwc3_meson_g12a_drvdata g12a_drvdata = {
137145
.otg_switch_supported = true,
138146
.clks = meson_g12a_clocks,
139147
.num_clks = ARRAY_SIZE(meson_g12a_clocks),
140148
.phy_names = meson_g12a_phy_names,
141149
.num_phys = ARRAY_SIZE(meson_g12a_phy_names),
150+
.setup_regmaps = dwc3_meson_g12a_setup_regmaps,
142151
};
143152

144153
static struct dwc3_meson_g12a_drvdata a1_drvdata = {
@@ -147,11 +156,13 @@ static struct dwc3_meson_g12a_drvdata a1_drvdata = {
147156
.num_clks = ARRAY_SIZE(meson_a1_clocks),
148157
.phy_names = meson_a1_phy_names,
149158
.num_phys = ARRAY_SIZE(meson_a1_phy_names),
159+
.setup_regmaps = dwc3_meson_g12a_setup_regmaps,
150160
};
151161

152162
struct dwc3_meson_g12a {
153163
struct device *dev;
154-
struct regmap *regmap;
164+
struct regmap *u2p_regmap[PHY_COUNT];
165+
struct regmap *usb_glue_regmap;
155166
struct reset_control *reset;
156167
struct phy *phys[PHY_COUNT];
157168
enum usb_dr_mode otg_mode;
@@ -168,11 +179,11 @@ static void dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a *priv,
168179
int i, enum phy_mode mode)
169180
{
170181
if (mode == PHY_MODE_USB_HOST)
171-
regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
182+
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
172183
U2P_R0_HOST_DEVICE,
173184
U2P_R0_HOST_DEVICE);
174185
else
175-
regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
186+
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
176187
U2P_R0_HOST_DEVICE, 0);
177188
}
178189

@@ -192,13 +203,12 @@ static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
192203
if (!strstr(priv->drvdata->phy_names[i], "usb2"))
193204
continue;
194205

195-
regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
206+
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
196207
U2P_R0_POWER_ON_RESET,
197208
U2P_R0_POWER_ON_RESET);
198209

199210
if (priv->drvdata->otg_switch_supported && i == USB2_OTG_PHY) {
200-
regmap_update_bits(priv->regmap,
201-
U2P_R0 + (U2P_REG_SIZE * i),
211+
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
202212
U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS,
203213
U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS);
204214

@@ -208,7 +218,7 @@ static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
208218
dwc3_meson_g12a_usb2_set_mode(priv, i,
209219
PHY_MODE_USB_HOST);
210220

211-
regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
221+
regmap_update_bits(priv->u2p_regmap[i], U2P_R0,
212222
U2P_R0_POWER_ON_RESET, 0);
213223
}
214224

@@ -217,46 +227,46 @@ static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
217227

218228
static void dwc3_meson_g12a_usb3_init(struct dwc3_meson_g12a *priv)
219229
{
220-
regmap_update_bits(priv->regmap, USB_R3,
230+
regmap_update_bits(priv->usb_glue_regmap, USB_R3,
221231
USB_R3_P30_SSC_RANGE_MASK |
222232
USB_R3_P30_REF_SSP_EN,
223233
USB_R3_P30_SSC_ENABLE |
224234
FIELD_PREP(USB_R3_P30_SSC_RANGE_MASK, 2) |
225235
USB_R3_P30_REF_SSP_EN);
226236
udelay(2);
227237

228-
regmap_update_bits(priv->regmap, USB_R2,
238+
regmap_update_bits(priv->usb_glue_regmap, USB_R2,
229239
USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK,
230240
FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK, 0x15));
231241

232-
regmap_update_bits(priv->regmap, USB_R2,
242+
regmap_update_bits(priv->usb_glue_regmap, USB_R2,
233243
USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK,
234244
FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK, 0x20));
235245

236246
udelay(2);
237247

238-
regmap_update_bits(priv->regmap, USB_R1,
248+
regmap_update_bits(priv->usb_glue_regmap, USB_R1,
239249
USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT,
240250
USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT);
241251

242-
regmap_update_bits(priv->regmap, USB_R1,
252+
regmap_update_bits(priv->usb_glue_regmap, USB_R1,
243253
USB_R1_P30_PCS_TX_SWING_FULL_MASK,
244254
FIELD_PREP(USB_R1_P30_PCS_TX_SWING_FULL_MASK, 127));
245255
}
246256

247257
static void dwc3_meson_g12a_usb_otg_apply_mode(struct dwc3_meson_g12a *priv)
248258
{
249259
if (priv->otg_phy_mode == PHY_MODE_USB_DEVICE) {
250-
regmap_update_bits(priv->regmap, USB_R0,
260+
regmap_update_bits(priv->usb_glue_regmap, USB_R0,
251261
USB_R0_U2D_ACT, USB_R0_U2D_ACT);
252-
regmap_update_bits(priv->regmap, USB_R0,
262+
regmap_update_bits(priv->usb_glue_regmap, USB_R0,
253263
USB_R0_U2D_SS_SCALEDOWN_MODE_MASK, 0);
254-
regmap_update_bits(priv->regmap, USB_R4,
264+
regmap_update_bits(priv->usb_glue_regmap, USB_R4,
255265
USB_R4_P21_SLEEP_M0, USB_R4_P21_SLEEP_M0);
256266
} else {
257-
regmap_update_bits(priv->regmap, USB_R0,
267+
regmap_update_bits(priv->usb_glue_regmap, USB_R0,
258268
USB_R0_U2D_ACT, 0);
259-
regmap_update_bits(priv->regmap, USB_R4,
269+
regmap_update_bits(priv->usb_glue_regmap, USB_R4,
260270
USB_R4_P21_SLEEP_M0, 0);
261271
}
262272
}
@@ -269,17 +279,17 @@ static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv)
269279
if (ret)
270280
return ret;
271281

272-
regmap_update_bits(priv->regmap, USB_R1,
282+
regmap_update_bits(priv->usb_glue_regmap, USB_R1,
273283
USB_R1_U3H_FLADJ_30MHZ_REG_MASK,
274284
FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20));
275285

276-
regmap_update_bits(priv->regmap, USB_R5,
286+
regmap_update_bits(priv->usb_glue_regmap, USB_R5,
277287
USB_R5_ID_DIG_EN_0,
278288
USB_R5_ID_DIG_EN_0);
279-
regmap_update_bits(priv->regmap, USB_R5,
289+
regmap_update_bits(priv->usb_glue_regmap, USB_R5,
280290
USB_R5_ID_DIG_EN_1,
281291
USB_R5_ID_DIG_EN_1);
282-
regmap_update_bits(priv->regmap, USB_R5,
292+
regmap_update_bits(priv->usb_glue_regmap, USB_R5,
283293
USB_R5_ID_DIG_TH_MASK,
284294
FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff));
285295

@@ -292,7 +302,8 @@ static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv)
292302
return 0;
293303
}
294304

295-
static const struct regmap_config phy_meson_g12a_usb3_regmap_conf = {
305+
static const struct regmap_config phy_meson_g12a_usb_glue_regmap_conf = {
306+
.name = "usb-glue",
296307
.reg_bits = 8,
297308
.val_bits = 32,
298309
.reg_stride = 4,
@@ -329,7 +340,7 @@ static enum phy_mode dwc3_meson_g12a_get_id(struct dwc3_meson_g12a *priv)
329340
{
330341
u32 reg;
331342

332-
regmap_read(priv->regmap, USB_R5, &reg);
343+
regmap_read(priv->usb_glue_regmap, USB_R5, &reg);
333344

334345
if (reg & (USB_R5_ID_DIG_SYNC | USB_R5_ID_DIG_REG))
335346
return PHY_MODE_USB_DEVICE;
@@ -405,7 +416,8 @@ static irqreturn_t dwc3_meson_g12a_irq_thread(int irq, void *data)
405416
dev_warn(priv->dev, "Failed to switch OTG mode\n");
406417
}
407418

408-
regmap_update_bits(priv->regmap, USB_R5, USB_R5_ID_DIG_IRQ, 0);
419+
regmap_update_bits(priv->usb_glue_regmap, USB_R5,
420+
USB_R5_ID_DIG_IRQ, 0);
409421

410422
return IRQ_HANDLED;
411423
}
@@ -440,7 +452,7 @@ static int dwc3_meson_g12a_otg_init(struct platform_device *pdev,
440452

441453
if (priv->otg_mode == USB_DR_MODE_OTG) {
442454
/* Ack irq before registering */
443-
regmap_update_bits(priv->regmap, USB_R5,
455+
regmap_update_bits(priv->usb_glue_regmap, USB_R5,
444456
USB_R5_ID_DIG_IRQ, 0);
445457

446458
irq = platform_get_irq(pdev, 0);
@@ -476,6 +488,41 @@ static int dwc3_meson_g12a_otg_init(struct platform_device *pdev,
476488
return 0;
477489
}
478490

491+
static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv,
492+
void __iomem *base)
493+
{
494+
int i;
495+
496+
priv->usb_glue_regmap = devm_regmap_init_mmio(priv->dev,
497+
base + G12A_GLUE_OFFSET,
498+
&phy_meson_g12a_usb_glue_regmap_conf);
499+
if (IS_ERR(priv->usb_glue_regmap))
500+
return PTR_ERR(priv->usb_glue_regmap);
501+
502+
/* Create a regmap for each USB2 PHY control register set */
503+
for (i = 0; i < priv->usb2_ports; i++) {
504+
struct regmap_config u2p_regmap_config = {
505+
.reg_bits = 8,
506+
.val_bits = 32,
507+
.reg_stride = 4,
508+
.max_register = U2P_R1,
509+
};
510+
511+
u2p_regmap_config.name = devm_kasprintf(priv->dev, GFP_KERNEL,
512+
"u2p-%d", i);
513+
if (!u2p_regmap_config.name)
514+
return -ENOMEM;
515+
516+
priv->u2p_regmap[i] = devm_regmap_init_mmio(priv->dev,
517+
base + (i * U2P_REG_SIZE),
518+
&u2p_regmap_config);
519+
if (IS_ERR(priv->u2p_regmap[i]))
520+
return PTR_ERR(priv->u2p_regmap[i]);
521+
}
522+
523+
return 0;
524+
}
525+
479526
static int dwc3_meson_g12a_probe(struct platform_device *pdev)
480527
{
481528
struct dwc3_meson_g12a *priv;
@@ -492,10 +539,12 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
492539
if (IS_ERR(base))
493540
return PTR_ERR(base);
494541

495-
priv->regmap = devm_regmap_init_mmio(dev, base,
496-
&phy_meson_g12a_usb3_regmap_conf);
497-
if (IS_ERR(priv->regmap))
498-
return PTR_ERR(priv->regmap);
542+
priv->drvdata = of_device_get_match_data(&pdev->dev);
543+
544+
priv->dev = dev;
545+
ret = priv->drvdata->setup_regmaps(priv, base);
546+
if (ret)
547+
return ret;
499548

500549
priv->vbus = devm_regulator_get_optional(dev, "vbus");
501550
if (IS_ERR(priv->vbus)) {
@@ -504,8 +553,6 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
504553
priv->vbus = NULL;
505554
}
506555

507-
priv->drvdata = of_device_get_match_data(&pdev->dev);
508-
509556
ret = devm_clk_bulk_get(dev,
510557
priv->drvdata->num_clks,
511558
priv->drvdata->clks);
@@ -518,7 +565,6 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
518565
return ret;
519566

520567
platform_set_drvdata(pdev, priv);
521-
priv->dev = dev;
522568

523569
priv->reset = devm_reset_control_get(dev, NULL);
524570
if (IS_ERR(priv->reset)) {

0 commit comments

Comments
 (0)