@@ -47,6 +47,7 @@ struct mtk_disp_pwm {
47
47
struct clk * clk_main ;
48
48
struct clk * clk_mm ;
49
49
void __iomem * base ;
50
+ bool enabled ;
50
51
};
51
52
52
53
static inline struct mtk_disp_pwm * to_mtk_disp_pwm (struct pwm_chip * chip )
@@ -66,25 +67,45 @@ static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset,
66
67
writel (value , address );
67
68
}
68
69
69
- static int mtk_disp_pwm_config (struct pwm_chip * chip , struct pwm_device * pwm ,
70
- int duty_ns , int period_ns )
70
+ static int mtk_disp_pwm_apply (struct pwm_chip * chip , struct pwm_device * pwm ,
71
+ const struct pwm_state * state )
71
72
{
72
73
struct mtk_disp_pwm * mdp = to_mtk_disp_pwm (chip );
73
74
u32 clk_div , period , high_width , value ;
74
75
u64 div , rate ;
75
76
int err ;
76
77
77
- err = clk_prepare_enable (mdp -> clk_main );
78
- if (err < 0 ) {
79
- dev_err (chip -> dev , "Can't enable mdp->clk_main: %pe\n" , ERR_PTR (err ));
80
- return err ;
78
+ if (state -> polarity != PWM_POLARITY_NORMAL )
79
+ return - EINVAL ;
80
+
81
+ if (!state -> enabled ) {
82
+ mtk_disp_pwm_update_bits (mdp , DISP_PWM_EN , mdp -> data -> enable_mask ,
83
+ 0x0 );
84
+
85
+ if (mdp -> enabled ) {
86
+ clk_disable_unprepare (mdp -> clk_mm );
87
+ clk_disable_unprepare (mdp -> clk_main );
88
+ }
89
+
90
+ mdp -> enabled = false;
91
+ return 0 ;
81
92
}
82
93
83
- err = clk_prepare_enable (mdp -> clk_mm );
84
- if (err < 0 ) {
85
- dev_err (chip -> dev , "Can't enable mdp->clk_mm: %pe\n" , ERR_PTR (err ));
86
- clk_disable_unprepare (mdp -> clk_main );
87
- return err ;
94
+ if (!mdp -> enabled ) {
95
+ err = clk_prepare_enable (mdp -> clk_main );
96
+ if (err < 0 ) {
97
+ dev_err (chip -> dev , "Can't enable mdp->clk_main: %pe\n" ,
98
+ ERR_PTR (err ));
99
+ return err ;
100
+ }
101
+
102
+ err = clk_prepare_enable (mdp -> clk_mm );
103
+ if (err < 0 ) {
104
+ dev_err (chip -> dev , "Can't enable mdp->clk_mm: %pe\n" ,
105
+ ERR_PTR (err ));
106
+ clk_disable_unprepare (mdp -> clk_main );
107
+ return err ;
108
+ }
88
109
}
89
110
90
111
/*
@@ -98,20 +119,22 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
98
119
* high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
99
120
*/
100
121
rate = clk_get_rate (mdp -> clk_main );
101
- clk_div = div_u64 (rate * period_ns , NSEC_PER_SEC ) >>
122
+ clk_div = div_u64 (rate * state -> period , NSEC_PER_SEC ) >>
102
123
PWM_PERIOD_BIT_WIDTH ;
103
124
if (clk_div > PWM_CLKDIV_MAX ) {
104
- clk_disable_unprepare (mdp -> clk_mm );
105
- clk_disable_unprepare (mdp -> clk_main );
125
+ if (!mdp -> enabled ) {
126
+ clk_disable_unprepare (mdp -> clk_mm );
127
+ clk_disable_unprepare (mdp -> clk_main );
128
+ }
106
129
return - EINVAL ;
107
130
}
108
131
109
132
div = NSEC_PER_SEC * (clk_div + 1 );
110
- period = div64_u64 (rate * period_ns , div );
133
+ period = div64_u64 (rate * state -> period , div );
111
134
if (period > 0 )
112
135
period -- ;
113
136
114
- high_width = div64_u64 (rate * duty_ns , div );
137
+ high_width = div64_u64 (rate * state -> duty_cycle , div );
115
138
value = period | (high_width << PWM_HIGH_WIDTH_SHIFT );
116
139
117
140
mtk_disp_pwm_update_bits (mdp , mdp -> data -> con0 ,
@@ -141,51 +164,15 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
141
164
mdp -> data -> con0_sel );
142
165
}
143
166
144
- clk_disable_unprepare (mdp -> clk_mm );
145
- clk_disable_unprepare (mdp -> clk_main );
146
-
147
- return 0 ;
148
- }
149
-
150
- static int mtk_disp_pwm_enable (struct pwm_chip * chip , struct pwm_device * pwm )
151
- {
152
- struct mtk_disp_pwm * mdp = to_mtk_disp_pwm (chip );
153
- int err ;
154
-
155
- err = clk_prepare_enable (mdp -> clk_main );
156
- if (err < 0 ) {
157
- dev_err (chip -> dev , "Can't enable mdp->clk_main: %pe\n" , ERR_PTR (err ));
158
- return err ;
159
- }
160
-
161
- err = clk_prepare_enable (mdp -> clk_mm );
162
- if (err < 0 ) {
163
- dev_err (chip -> dev , "Can't enable mdp->clk_mm: %pe\n" , ERR_PTR (err ));
164
- clk_disable_unprepare (mdp -> clk_main );
165
- return err ;
166
- }
167
-
168
167
mtk_disp_pwm_update_bits (mdp , DISP_PWM_EN , mdp -> data -> enable_mask ,
169
168
mdp -> data -> enable_mask );
169
+ mdp -> enabled = true;
170
170
171
171
return 0 ;
172
172
}
173
173
174
- static void mtk_disp_pwm_disable (struct pwm_chip * chip , struct pwm_device * pwm )
175
- {
176
- struct mtk_disp_pwm * mdp = to_mtk_disp_pwm (chip );
177
-
178
- mtk_disp_pwm_update_bits (mdp , DISP_PWM_EN , mdp -> data -> enable_mask ,
179
- 0x0 );
180
-
181
- clk_disable_unprepare (mdp -> clk_mm );
182
- clk_disable_unprepare (mdp -> clk_main );
183
- }
184
-
185
174
static const struct pwm_ops mtk_disp_pwm_ops = {
186
- .config = mtk_disp_pwm_config ,
187
- .enable = mtk_disp_pwm_enable ,
188
- .disable = mtk_disp_pwm_disable ,
175
+ .apply = mtk_disp_pwm_apply ,
189
176
.owner = THIS_MODULE ,
190
177
};
191
178
0 commit comments